1、pom文件
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.5.4</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract-platform</artifactId>
<version>4.0.0-1.4.4</version>
</dependency>
2、ImageUtil.class,做降噪处理
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* @author ZhaoXu
* @date 2021/11/25 15:21
*/
public class ImageUtil {
public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
BufferedImage grayBufferedImage = new BufferedImage(width, height, bufferedImage.getType());
for (int i = 0; i < bufferedImage.getWidth(); i++) {
for (int j = 0; j < bufferedImage.getHeight(); j++) {
final int color = bufferedImage.getRGB(i, j);
final int r = (color >> 16) & 0xff;
final int g = (color >> 8) & 0xff;
final int b = color & 0xff;
int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b);
int newPixel = colorToRGB(255, gray, gray, gray);
grayBufferedImage.setRGB(i, j, newPixel);
}
}
return grayBufferedImage;
}
/**
* 颜色分量转换为RGB值
*
* @param alpha
* @param red
* @param green
* @param blue
* @return
*/
private static int colorToRGB(int alpha, int red, int green, int blue) {
int newPixel = 0;
newPixel += alpha;
newPixel = newPixel << 8;
newPixel += red;
newPixel = newPixel << 8;
newPixel += green;
newPixel = newPixel << 8;
newPixel += blue;
return newPixel;
}
public static BufferedImage binaryImage(BufferedImage image) throws Exception {
int w = image.getWidth();
int h = image.getHeight();
float[] rgb = new float[3];
double[][] zuobiao = new double[w][h];
int black = new Color(0, 0, 0).getRGB();
int white = new Color(255, 255, 255).getRGB();
BufferedImage bi= new BufferedImage(w, h,
BufferedImage.TYPE_BYTE_BINARY);;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pixel = image.getRGB(x, y);
rgb[0] = (pixel & 0xff0000) >> 16;
rgb[1] = (pixel & 0xff00) >> 8;
rgb[2] = (pixel & 0xff);
float avg = (rgb[0]+rgb[1]+rgb[2])/3;
zuobiao[x][y] = avg;
}
}
//这里是阈值,白底黑字还是黑底白字,大多数情况下建议白底黑字,后面都以白底黑字为例
double SW = 192;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if (zuobiao[x][y] < SW) {
bi.setRGB(x, y, black);
}else{
bi.setRGB(x, y, white);
}
}
}
return bi;
}
// 自己加周围8个灰度值再除以9,算出其相对灰度值
public static double getGray(double[][] zuobiao, int x, int y, int w, int h) {
double rs = zuobiao[x][y] + (x == 0 ? 255 : zuobiao[x - 1][y]) + (x == 0 || y == 0 ? 255 : zuobiao[x - 1][y - 1])
+ (x == 0 || y == h - 1 ? 255 : zuobiao[x - 1][y + 1]) + (y == 0 ? 255 : zuobiao[x][y - 1])
+ (y == h - 1 ? 255 : zuobiao[x][y + 1]) + (x == w - 1 ? 255 : zuobiao[x + 1][y])
+ (x == w - 1 || y == 0 ? 255 : zuobiao[x + 1][y - 1])
+ (x == w - 1 || y == h - 1 ? 255 : zuobiao[x + 1][y + 1]);
return rs / 9;
}
/**
* 降噪,以1个像素点为单位(实际使用中可以循环降噪,或者把单位可以扩大为多个像素点)
* @param image
* @return
*/
public static BufferedImage denoise(BufferedImage image){
int w = image.getWidth();
int h = image.getHeight();
int white = new Color(255, 255, 255).getRGB();
if(isWhite(image.getRGB(1, 0)) && isWhite(image.getRGB(0, 1)) && isWhite(image.getRGB(1, 1))){
image.setRGB(0,0,white);
}
if(isWhite(image.getRGB(w-2, 0)) && isWhite(image.getRGB(w-1, 1)) && isWhite(image.getRGB(w-2, 1))){
image.setRGB(w-1,0,white);
}
if(isWhite(image.getRGB(0, h-2)) && isWhite(image.getRGB(1, h-1)) && isWhite(image.getRGB(1, h-2))){
image.setRGB(0,h-1,white);
}
if(isWhite(image.getRGB(w-2, h-1)) && isWhite(image.getRGB(w-1, h-2)) && isWhite(image.getRGB(w-2, h-2))){
image.setRGB(w-1,h-1,white);
}
for(int x = 1; x < w-1; x++){
int y = 0;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x+1, y))){
size++;
}
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x-1, y+1))){
size++;
}
if(isWhite(image.getRGB(x+1, y+1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
for(int x = 1; x < w-1; x++){
int y = h-1;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x+1, y))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y-1))){
size++;
}
if(isWhite(image.getRGB(x-1, y-1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
for(int y = 1; y < h-1; y++){
int x = 0;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x+1, y))){
size++;
}
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y+1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
for(int y = 1; y < h-1; y++){
int x = w - 1;
if(isBlack(image.getRGB(x, y))){
int size = 0;
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
//斜上下为空时,去掉此点
if(isWhite(image.getRGB(x-1, y+1))){
size++;
}
if(isWhite(image.getRGB(x-1, y-1))){
size++;
}
if(size>=5){
image.setRGB(x,y,white);
}
}
}
//降噪,以1个像素点为单位
for(int y = 1; y < h-1; y++){
for(int x = 1; x < w-1; x++){
if(isBlack(image.getRGB(x, y))){
int size = 0;
//上下左右均为空时,去掉此点
if(isWhite(image.getRGB(x-1, y))){
size++;
}
if(isWhite(image.getRGB(x+1, y))){
size++;
}
//上下均为空时,去掉此点
if(isWhite(image.getRGB(x, y+1))){
size++;
}
if(isWhite(image.getRGB(x, y-1))){
size++;
}
//斜上下为空时,去掉此点
if(isWhite(image.getRGB(x-1, y+1))){
size++;
}
if(isWhite(image.getRGB(x+1, y-1))){
size++;
}
if(isWhite(image.getRGB(x+1, y+1))){
size++;
}
if(isWhite(image.getRGB(x-1, y-1))){
size++;
}
if(size>=8){
image.setRGB(x,y,white);
}
}
}
}
return image;
}
public static boolean isBlack(int colorInt)
{
Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() <= 300)
{
return true;
}
return false;
}
public static boolean isWhite(int colorInt)
{
Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() > 300)
{
return true;
}
return false;
}
public static int isBlack(int colorInt, int whiteThreshold) {
final Color color = new Color(colorInt);
if (color.getRed() + color.getGreen() + color.getBlue() <= whiteThreshold) {
return 1;
}
return 0;
}
}
3、EmobileLdMonitor.class
import net.sourceforge.tess4j.*;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.lept;
import org.bytedeco.javacpp.tesseract;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import static org.bytedeco.javacpp.lept.pixDestroy;
import static org.bytedeco.javacpp.lept.pixRead;
/**
* @author ZhaoXu
* @date 2021/11/24 16:27
*/
public class EmobileLdMonitor {
static String language = "chi_sim";
final static Logger LOGGER = LoggerFactory.getLogger(EmobileLdMonitor.class);
static int pictureLength = 600;
static int pictureHeight = 568;
static int atX;
static int atY;
static String langPath = "src/main/resources/tessdata";
static String imageUrl = "src/main/resources/screens/test.png";
static String ldName = "陈小龙";
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
// 获取屏幕的尺寸
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) (screenSize.getWidth() / 1);
int height = (int) (screenSize.getHeight() / 1);
atX = width - 235;
atY = height - 185;
while (true) {
EmobileLdMonitor.screen();
// String ocr = ocrTesseractOCR();
List<Word> words = ocrTess4j();
words.forEach(word -> {
System.out.print(word.getText());
int x = word.getBoundingBox().x;
int y = word.getBoundingBox().y;
if (ldName.contains(word.getText())) {
robot.mouseMove(atX + 1, atY + 1);
//按下和释放鼠标左键,选定工程
robot.mousePress(KeyEvent.BUTTON1_MASK);
robot.mouseRelease(KeyEvent.BUTTON1_MASK);
}
});
System.out.println();
Thread.sleep(3000);
}
}
/**
* 识别图片中的中文
*
* @return
* @throws TesseractException
* @throws IOException
*/
public static List<Word> ocrTess4j() throws TesseractException, IOException {
ITesseract instance = new Tesseract();
// 指定为中文识别
instance.setLanguage(language);
// 指定训练数据集合的路径
instance.setDatapath(langPath);
instance.setOcrEngineMode(1);
instance.setTessVariable("user_defined_dpi", "1080");
// 指定识别图片
File imgDir = new File(imageUrl);
BufferedImage bufferedImage = ImageIO.read(imgDir);
int level = ITessAPI.TessPageIteratorLevel.RIL_SYMBOL;
// String s = instance.doOCR(imgDir);
List<Word> result = instance.getWords(bufferedImage, level);
for (int i = 0; i < result.size(); i++) {
Word word = result.get(i);
Rectangle boundingBox = word.getBoundingBox();
int x = boundingBox.x;
int y = boundingBox.y;
}
return result;
}
/**
* 识别图片中的中文 TesseractOCR
*
* @return
* @throws TesseractException
* @throws IOException
*/
public static String ocrTesseractOCR() throws IOException {
//创建字节容器。
BytePointer outtext;
//启动识别器
tesseract.TessBaseAPI ocrapi = new tesseract.TessBaseAPI();
//初始化识别器的语言包
if (ocrapi.Init(langPath, language) != 0) {
System.out.println("Could not initialize tesseract");
return null;
}
//读取源图片
lept.PIX image = pixRead(imageUrl);
//识别器装入图片
ocrapi.SetImage(image);
ocrapi.set_min_orientation_margin(1.0);
//识别器识别进行段。
outtext = ocrapi.GetUTF8Text();
try {
return outtext.getString("utf-8");
} finally {
//最后释放资源
ocrapi.End();
outtext.deallocate();
pixDestroy(image);
}
}
/**
* 截屏幕,右下角
*
* @throws IOException
* @throws AWTException
*/
public static void screen() throws Exception {
// 截取屏幕
BufferedImage textImage = new Robot().createScreenCapture(new Rectangle(atX, atY, 150, 150));
// BufferedImage textImage = new Robot().createScreenCapture(new Rectangle(screenSize));
textImage = ImageUtil.grayImage(textImage);
textImage = ImageUtil.binaryImage(textImage);
textImage = ImageUtil.denoise(textImage);
// 设置日期格式,作为目录名
DateFormat dfDirectory = new SimpleDateFormat("yyyyMMdd");
// 创建一个用于保存图片的文件夹
File screenCaptureDirectory = new File("src/main/resources/screens");
if (!screenCaptureDirectory.exists()) {
screenCaptureDirectory.mkdirs();
System.out.println("The directory " + screenCaptureDirectory.getName() + " is created.");
}
// 设置日期格式,作为图片名
DateFormat dfImageName = new SimpleDateFormat("yyyyMMddhhmmss");
// 指定路径,并以特定的日期格式作为图片的名称
File imageFile = new File(screenCaptureDirectory, ("test.png"));
// 以指定的图片格式将截取的图片写到指定的文件
ImageIO.write(textImage, "png", imageFile);
ImageUtil.reduceImg(imageUrl, pictureLength, pictureHeight);
// 自动打开图片
// if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
// Desktop.getDesktop().open(imageFile);
// }
}
}
版权声明:本文为qq_39898191原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。