上一篇使用 Tess4J 进行 OCR 识别,虽然能识别一些简单的验证码,但是验证码有干扰线就识别不了。
这一篇讲下如何使用 OpenCV 去除干扰线。
org.bytedeco
javacv-platform
1.5.5
OpenCV用C++语言编写,提供了接口,我这里使用 javacv 它里面就有 opencv ,不过这样依赖会将所有平台的 jar 包都拉取下来,项目接近1G大小,可以看下我的另外一篇博文精简 javacv 的 jar包。https://blog.csdn.net/u014644574/article/details/122067708
二值图(前景黑色,背景白色)
腐蚀:去除图像表面像素,将图像逐步缩小,以达到消去点状图像的效果;作用就是将图像边缘的毛刺剔除掉
膨胀:将图像表面不断扩散以达到去除小孔的效果;作用就是将目标的边缘或者是内部的坑填掉
使用相同次数的腐蚀和膨胀,可以使目标表面更平滑;但也有场景限制,就是如果去噪不干净的话,会出现意想不到的结果,尽量别使用大概的效果,适合降噪比较干净的图
javacv 是用jni的方式调用的 opencv,也可以是说上是对 opencv 的封装,不用安装 opencv 和配置加载dll动态库。System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
注意:
1、注意我的导包方式(重点)
2、二值化 threshold() 第3个参数,要根据自己的实际情况调整大小,一般就是100-200之间。
package com.demo.verify;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Size;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_highgui.*;//包含了所有图形接口函数
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*; //COLOR_RGB2GRAY
//得到灰度图像
public class Test1 {
public static void main(String[] args) throws Exception {
String filePath = "C:\verify\\7zbn.png";
Mat image = imread(filePath); // 加载图像
imshow("原图", image);
//高斯滤波器(GaussianFilter)对图像进行平滑处理。
//GaussianBlur(image, image, new Size(3, 3), 0);
//这里可以new一个Mat来接收,也可以直接使用原来的image接收cvtColor(image, image, CV_BGRA2GRAY);
Mat gray = new Mat();
cvtColor(image, gray, CV_BGRA2GRAY);// 灰度化
imshow("灰度", gray);
//medianBlur(gray, gray, 3); //中值滤波
Mat bin = new Mat();
//第三参数thresh,要根据自己的实际情况改变大小调试打印看一下。一般取100-200
threshold(gray, bin, 150, 255, THRESH_BINARY);// 二值化
imshow("二值化", bin);
bitwise_not(bin, bin); // 反色,即黑色变白色,白色变黑色
Mat corrode = new Mat();
Mat expand = new Mat();
Mat kelner = getStructuringElement(MORPH_RECT, new Size(3, 3), new Point(-1, -1));
erode(bin, corrode, kelner); // 腐蚀
dilate(corrode, expand, kelner); // 膨胀
bitwise_not(expand, expand); // 反色,既黑色变白色,白色变黑色
imshow("膨胀", expand);
bitwise_not(bin, bin); // 反色,即黑色变白色,白色变黑色
//保存二值化图像
String imageFile = filePath + ".png";
imwrite(imageFile, bin);
waitKey(0);
}
}
package com.demo.verify;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Size;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_highgui.*;//包含了所有图形接口函数
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*; //COLOR_RGB2GRAY
//得到灰度图像
public class Test1 {
public static void main(String[] args) throws Exception {
String filePath = "C:/verify/awy6.png";
Mat image = imread(filePath); // 加载图像
imshow("原图", image);
//高斯滤波器(GaussianFilter)对图像进行平滑处理。
//GaussianBlur(image, image, new Size(3, 3), 0);
//这里可以new一个Mat来接收,也可以直接使用原来的image接收cvtColor(image, image, CV_BGRA2GRAY);
Mat gray = new Mat();
cvtColor(image, gray, CV_BGRA2GRAY);// 灰度化
imshow("灰度", gray);
//medianBlur(gray, gray, 3); //中值滤波
Mat bin = new Mat();
//第三参数thresh,要根据自己的实际情况改变大小调试打印看一下。一般取100-200
threshold(gray, bin, 90, 255, THRESH_BINARY);// 二值化
imshow("二值化", bin);
bitwise_not(bin, bin); // 反色,即黑色变白色,白色变黑色
Mat corrode = new Mat();
Mat expand = new Mat();
Mat kelner = getStructuringElement(MORPH_RECT, new Size(3, 3), new Point(-1, -1));
erode(bin, corrode, kelner); // 腐蚀
dilate(corrode, expand, kelner); // 膨胀
bitwise_not(expand, expand); // 反色,既黑色变白色,白色变黑色
imshow("膨胀", expand);
bitwise_not(bin, bin); // 反色,即黑色变白色,白色变黑色
//保存二值化图像
String imageFile = filePath + ".png";
imwrite(imageFile, bin);
waitKey(0);
}
}