原图
矫正后
根据文字矫正文本区域
public static Mat imgCorrection(Mat srcImage) {
Mat binary = ImgBinarization(srcImage);
Mat preprocess = preprocess(binary);
List<RotatedRect> rects = findTextRegion(preprocess) ;
Mat correction = correction(rects,srcImage);
return correction;
}
图片二值化
public static Mat ImgBinarization(Mat srcImage){
Mat gray_image = null;
try {
gray_image = new Mat(srcImage.height(), srcImage.width(), CvType.CV_8UC1);
Imgproc.cvtColor(srcImage,gray_image,Imgproc.COLOR_RGB2GRAY);
} catch (Exception e) {
gray_image = srcImage.clone();
gray_image.convertTo(gray_image, CvType.CV_8UC1);
System.out.println("原文异常,已处理...");
}
Mat thresh_image = new Mat(srcImage.height(), srcImage.width(), CvType.CV_8UC1);
Imgproc.threshold(gray_image, thresh_image,100, 255, Imgproc.THRESH_BINARY);
return thresh_image;
}
膨胀与腐蚀
public static Mat preprocess(Mat binary){
Mat element1 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20, 4));
Mat element2 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, 1));
Mat dilate1 = new Mat();
Imgproc.dilate(binary, dilate1, element2);
Mat erode1 = new Mat();
Imgproc.erode(dilate1, erode1, element1);
Mat dilate2 = new Mat();
Imgproc.dilate(erode1, dilate2, element2);
return dilate2;
}
获取文字区域
public static List<RotatedRect> findTextRegion(Mat img)
{
List<RotatedRect> rects = new ArrayList<RotatedRect>();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(img, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
int img_width = img.width();
int img_height = img.height();
int size = contours.size();
for (int i = 0; i < size; i++){
double area = Imgproc.contourArea(contours.get(i));
if (area < 1000)
continue;
double epsilon = 0.001*Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true);
MatOfPoint2f approxCurve = new MatOfPoint2f();
Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(i).toArray()), approxCurve, epsilon, true);
RotatedRect rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
int m_width = rect.boundingRect().width;
int m_height = rect.boundingRect().height;
if (m_width < m_height)
continue;
if(img_width == rect.boundingRect().br().x)
continue;
if(img_height == rect.boundingRect().br().y)
continue;
rects.add(rect);
}
return rects;
}
倾斜矫正
public static Mat correction(List<RotatedRect> rects,Mat srcImage) {
double degree = 0;
double degreeCount = 0;
for(int i = 0; i < rects.size();i++){
if(rects.get(i).angle >= -90 && rects.get(i).angle < -45){
degree = rects.get(i).angle;
if(rects.get(i).angle != 0){
degree += 90;
}
}
if(rects.get(i).angle > -45 && rects.get(i).angle <= 0){
degree = rects.get(i).angle;
}
if(rects.get(i).angle <= 90 && rects.get(i).angle > 45){
degree = rects.get(i).angle;
if(rects.get(i).angle != 0){
degree -= 90;
}
}
if(rects.get(i).angle < 45 && rects.get(i).angle >= 0){
degree = rects.get(i).angle;
}
if(degree > -5 && degree < 5){
degreeCount += degree;
}
}
if(degreeCount != 0){
degree = degreeCount/rects.size();
}
Point center = new Point(srcImage.cols() / 2, srcImage.rows() / 2);
Mat rotm = Imgproc.getRotationMatrix2D(center, degree, 1.0);
Mat dst = new Mat();
Imgproc.warpAffine(srcImage, dst, rotm, srcImage.size(), Imgproc.INTER_LINEAR, 0, new Scalar(255, 255, 255));
return dst;
}