javacv简单文本倾斜矫正

使用javacv+maven+javacpp做出简单文本倾斜矫正
示例图片:
这里写图片描述
使用旋转后的效果图片:
这里写图片描述

package com.javacv.test;

import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.opencv_core.*;

import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgcodecs.cvLoadImage;
import static org.bytedeco.javacpp.opencv_imgproc.*;

public class test2 {
    //自动倾斜
    public static void main(String[] args) {
        IplImage image = null;
        image = cvLoadImage("c://test.jpg");
        IplImage copy = cvCloneImage(image);
        //建立储存边缘检测结果图像canImage
        IplImage canImage = cvCreateImage(cvGetSize(copy), IPL_DEPTH_8U, 1);
        //进行边缘检测
        cvCanny(copy, canImage, 30, 200, 3);
        //进行hough变换
        CvMemStorage storage = cvCreateMemStorage();
        CvSeq lines = null;
        //霍夫函数检测直线
        //canImage输入8-比特、单通道(二值)图像,当用CV_HOUGH_PROBABILISTIC方法检测的时候其内容会被函数改变
        //line_storage 检测到的线段存储仓.可以是内存存储仓(此种情况下,一个线段序列在存储仓中被创建,并且由函数返回),
        // 或者是包含线段参数的特殊类型(见下面)的具有单行/单列的矩阵(CvMat*)。矩阵头为函数所修改,
        // 使得它的 cols/rows 将包含一组检测到的线段。如果 line_storage 是矩阵,而实际线段的数目超过矩阵尺寸,
        // 那么最大可能数目的线段被返回(线段没有按照长度、可信度或其它指标排序).
        //method Hough 变换变量,是下面变量的其中之一:
        //  CV_HOUGH_STANDARD - 传统或标准 Hough 变换. 每一个线段由两个浮点数 (ρ, θ) 表示,其中 ρ 是直线与原点(0,0) 之间的距离,θ 线段与 x-轴之间的夹角。因此,矩阵类型必须是 CV_32FC2 type.
        //  CV_HOUGH_PROBABILISTIC- 概率 Hough 变换(如果图像包含一些长的线性分割,则效率更高). 它返回线段分割而不是整个线段。每个分割用起点和终点来表示,所以矩阵(或创建的序列)类型是 CV_32SC4.
        //  CV_HOUGH_MULTI_SCALE - 传统 Hough 变换的多尺度变种。线段的编码方式与 CV_HOUGH_STANDARD 的一致。
        //rho 以象素为单位的距离精度,一般取1
        //theta 以弧度为单位角度精度,一般取CV_PI/180
        //threshold 阈值参数。当在一条直线上的像素点数大于threshold时,才将该直线作为检测结果显示出来。该值越大,得到直线越少
        lines = cvHoughLines2(canImage, storage, CV_HOUGH_STANDARD, 1, CV_PI / 180, 20);
        //统计与竖直夹角<30度的直线个数以及其夹角和
        int numLine = 0;
        double sumAng = 0;
        int aa = 0;
        int bb = 0;
        for (int i = 0; i < lines.total(); i++) {
            BytePointer bytePointer = cvGetSeqElem(lines, i);//用GetSeqElem获得直线
            double line = bytePointer.getDouble();
            CvRect r = new CvRect(cvGetSeqElem(lines, i));
            int x = r.x(), y = r.y(), w = r.width(), h = r.height();
            double theta = line;  //获取角度 为弧度制
            if (theta < 0.5 && x > 0) {
                aa = aa + 1;
            }
            if (theta < 2 && theta > 0.5 && x > 0) {
                bb = bb + 1;
            }
        }
        for (int i = 0; i < lines.total(); i++) {
            BytePointer bytePointer = cvGetSeqElem(lines, i);//用GetSeqElem获得直线
            CvRect r = new CvRect(cvGetSeqElem(lines, i));
            int x = r.x(), y = r.y(), w = r.width(), h = r.height();
            double line = bytePointer.getDouble();
            double theta = line;  //获取角度 为弧度制
            if (aa > bb) {
                if (theta < CV_PI / 2) {
                    sumAng = sumAng + theta;
                    numLine = numLine + 1;
                }
            } else {
                if (theta < CV_PI || theta > CV_PI / 2) {
                    sumAng = sumAng + theta;
                    numLine = numLine + 1;
                }
            }
        }
        //计算出平均倾斜角,anAng为角度制
        double angle = 0;
        angle = -(sumAng / numLine) * 180 / CV_PI;
        //Define Rotational Matrix
        CvMat mapMatrix = cvCreateMat(2, 3, CV_32FC1);

        //Define Mid Point
        CvPoint2D32f centerPoint = new CvPoint2D32f();
        centerPoint.x(copy.width() / 2);
        centerPoint.y(copy.height() / 2);

        //Get Rotational Matrix
        cv2DRotationMatrix(centerPoint, angle, 1.0, mapMatrix);
        //建立输出图像RotateRow
        double a = Math.sin(sumAng / numLine);
        double b = Math.cos(sumAng / numLine);
        //size中的图像的宽度和高度,depth图像像素的位深度,channels每个像素的通道数
        IplImage rotatedImage = cvCreateImage(cvGetSize(copy), copy.depth(), copy.nChannels());
        //Rotate the Image
        cvWarpAffine(copy, rotatedImage, mapMatrix, CV_INTER_CUBIC + CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
        cvReleaseImage(copy);
        cvReleaseMat(mapMatrix);
        //IplImage转Mat
        Mat mat2 = new Mat(rotatedImage);
        //JavaCVUtil.imWrite(mat2, "c://0730//000602.tif");
        JavaCVUtil.imWrite(mat2, "c://test9.jpg");
    }
}

pom.xml代码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yinuojingye</groupId>
    <artifactId>helloJavaCV</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <javacpp.platform.dependencies>windows-x86_64</javacpp.platform.dependencies>
        <javacpp.platform.android-arm>android-arm</javacpp.platform.android-arm>
        <javacpp.platform.android-arm64>android-arm64</javacpp.platform.android-arm64>
        <javacpp.platform.android-x86>android-x86</javacpp.platform.android-x86>
        <javacpp.platform.android-x86_64>android-x86_64</javacpp.platform.android-x86_64>
        <javacpp.platform.ios-arm>ios-arm</javacpp.platform.ios-arm>
        <javacpp.platform.ios-arm64>ios-arm64</javacpp.platform.ios-arm64>
        <javacpp.platform.ios-x86>ios-x86</javacpp.platform.ios-x86>
        <javacpp.platform.ios-x86_64>ios-x86_64</javacpp.platform.ios-x86_64>
        <javacpp.platform.linux-armhf>linux-armhf</javacpp.platform.linux-armhf>
        <javacpp.platform.linux-arm64>linux-arm64</javacpp.platform.linux-arm64>
        <javacpp.platform.linux-ppc64le>linux-ppc64le</javacpp.platform.linux-ppc64le>
        <javacpp.platform.linux-x86>linux-x86</javacpp.platform.linux-x86>
        <javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64>
        <javacpp.platform.macosx-x86_64>macosx-x86_64</javacpp.platform.macosx-x86_64>
        <javacpp.platform.windows-x86>windows-x86</javacpp.platform.windows-x86>
        <javacpp.platform.windows-x86_64>windows-x86_64</javacpp.platform.windows-x86_64>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bytedeco.javacpp-presets</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv</artifactId>
            <version>3.4.1-1.4.1</version>
            <classifier>${javacpp.platform.dependencies}</classifier>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg -->
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg</artifactId>
            <version>3.4.2-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg</artifactId>
            <version>3.4.2-1.4.1</version>
            <classifier>${javacpp.platform.dependencies}</classifier>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.3.1</version>
        </dependency>
    </dependencies>
</project>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值