Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用OpenCV查找图像上数字的边界框 我试图在下面的3幅图像中间找到数字的包围盒。_Java_C++_Opencv_Bounding Box - Fatal编程技术网

Java 使用OpenCV查找图像上数字的边界框 我试图在下面的3幅图像中间找到数字的包围盒。

Java 使用OpenCV查找图像上数字的边界框 我试图在下面的3幅图像中间找到数字的包围盒。,java,c++,opencv,bounding-box,Java,C++,Opencv,Bounding Box,这里有3张我尝试使用的示例卡 我使用的代码是第一个答案中提供的代码的基础(几乎是完整的副本),虽然转换为java(C++中的答案很好),并且为轮廓合并的大小添加了参数(在我的代码中定义为sisial-and sisiValigic),这是我在下面的图像中播放的两个参数。 MatOfPoint2f approxCurve = new MatOfPoint2f(); Mat imgMAT = new Mat(); Utils.bitmapToMat(bmp32, imgMAT); Mat

这里有3张我尝试使用的示例卡

<>我使用的代码是第一个答案中提供的代码的基础(几乎是完整的副本),虽然转换为java(C++中的答案很好),并且为轮廓合并的大小添加了参数(在我的代码中定义为sisial-and sisiValigic),这是我在下面的图像中播放的两个参数。
MatOfPoint2f approxCurve = new MatOfPoint2f();

Mat imgMAT = new Mat();
Utils.bitmapToMat(bmp32, imgMAT);

Mat grad = new Mat();

Imgproc.cvtColor(imgMAT, grad, Imgproc.COLOR_BGR2GRAY);

Mat img_sobel = new Mat();
Mat img_threshold = new Mat();

Imgproc.Sobel(grad, img_sobel, CvType.CV_8U, 1, 0, 3, 1, 0, Core.BORDER_DEFAULT);

Imgproc.threshold(img_sobel, img_threshold, 0, 255, Imgproc.THRESH_OTSU + Imgproc.THRESH_BINARY);

Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeHorizontal, sizeVertical));

Imgproc.morphologyEx(img_threshold, img_threshold, Imgproc.MORPH_CLOSE, element);

Imgproc.cvtColor(imgMAT, imgMAT, Imgproc.COLOR_BGR2GRAY);


List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(img_threshold, contours, new Mat(), Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE, new org.opencv.core.Point(0, 0));

for (int i = 0; i < contours.size(); i++) {

    //Convert contours(i) from MatOfPoint to MatOfPoint2f
    MatOfPoint2f contour2f = new MatOfPoint2f( contours.get(i).toArray() );

    //Processing on mMOP2f1 which is in type MatOfPoint2f
    double approxDistance = Imgproc.arcLength(contour2f, true)*0.02;
    Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);

    //Convert back to MatOfPoint
    MatOfPoint points = new MatOfPoint( approxCurve.toArray() );

    // Get bounding rect of contour
    org.opencv.core.Rect rect = Imgproc.boundingRect(points);

    Imgproc.rectangle(imgMAT, rect.tl(), rect.br(), new Scalar(0, 255, 0), 2);
}
MatOfPoint2f approxCurve=新的MatOfPoint2f();
Mat imgMAT=新Mat();
比特映射器(bmp32,imgMAT);
材料梯度=新材料();
Imgproc.cvt颜色(imgMAT、grad、Imgproc.COLOR\u bgr2灰色);
Mat img_sobel=新Mat();
Mat img_阈值=新Mat();
Imgproc.Sobel(grad,img_Sobel,CvType.CV_8U,1,0,3,1,0,Core.BORDER_默认值);
Imgproc.threshold(img_sobel,img_threshold,0,255,Imgproc.THRESH_OTSU+Imgproc.THRESH_二进制);
Mat element=Imgproc.getStructuringElement(Imgproc.morp_RECT,新尺寸(水平尺寸,垂直尺寸));
Imgproc.morphologyEx(img_阈值,img_阈值,Imgproc.morp_关闭,元素);
Imgproc.cvt颜色(imgMAT,imgMAT,Imgproc.COLOR_bgr2灰色);
列表等高线=新的ArrayList();
Imgproc.findContours(img_阈值,等高线,new Mat(),Imgproc.RETR_CCOMP,Imgproc.CHAIN_近似值,new org.opencv.core.Point(0,0));
对于(int i=0;i
我已经绘制了不同数量的等高线,但是我找不到一种方法来隔离我想要的等高线。以下是用尺寸输入参数绘制的区域轮廓。正如您在第二张图片中看到的,这正是我想要的,并且已经勾勒出了整个数字,而不是每个部分

1:尺寸参数输入:17,5

2:尺寸参数输入:23,7

3:尺寸参数输入:23,13

因此,我需要在以下方面得到帮助:

隔离中间的四个轮廓并找到将这些轮廓合并到的方法。 我曾考虑过将与给定纵横比匹配的轮廓裁剪到一个包含所有轮廓的边界框中,但也有其他具有类似比例的周围轮廓

  • 找到自动选择正确尺寸参数的方法(因为每种卡类型需要不同的参数来隔离数字)
  • 除了尝试所有3种尺寸的输入和看到预期轮廓外,我可以使用当前颜色作为卡类型的指示器,然后使用此卡类型的参数。但是,任何其他的建议都会有帮助,因为我觉得有更好的方法来做到这一点

    非常感谢

    在我百忙之中,我可以帮你找到一些绝种的。请查找下面的代码,它将帮助您获得前两幅图像。对第三幅图像进行微调。只需使用形态学操作即可获得所需的输出

    //#include "stdafx.h"
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    #include "tchar.h"
    using namespace cv;
    using namespace std;
    
    #define INPUT_FILE              "p.jpg"
    #define OUTPUT_FOLDER_PATH      string("")
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        Mat large = imread(INPUT_FILE);
        Mat rgb;
        // downsample and use it for processing
        pyrDown(large, rgb);
        Mat small;
        cvtColor(rgb, small, CV_BGR2GRAY);
        // morphological gradient
        Mat grad;
        Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(2, 2));
        Mat morphKernel1 = getStructuringElement(MORPH_ELLIPSE, Size(1, 1));
        morphologyEx(small, grad, MORPH_GRADIENT, morphKernel);
        // binarize
        Mat bw;
        threshold(grad, bw, 5.0, 50.0, THRESH_BINARY | THRESH_OTSU);
        // connect horizontally oriented regions
        Mat connected;
        morphKernel = getStructuringElement(MORPH_RECT, Size(9, 1));
        morphologyEx(bw, connected, MORPH_CLOSE, morphKernel);
        morphologyEx(bw, connected, MORPH_OPEN, morphKernel1);
        morphologyEx(connected, connected, MORPH_CLOSE, morphKernel);
        morphologyEx(connected, connected, MORPH_CLOSE, morphKernel);
         morphologyEx(connected, connected, MORPH_CLOSE, morphKernel);
        // find contours
        Mat mask = Mat::zeros(bw.size(), CV_8UC1);
        vector<vector<Point>> contours;
        vector<Vec4i> hierarchy;
        findContours(connected, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
        // filter contours
        int y=0;
        for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
        {
            Rect rect = boundingRect(contours[idx]);
            Mat maskROI(mask, rect);
            maskROI = Scalar(0, 0, 0);
            // fill the contour
            drawContours(mask, contours, idx, Scalar(255, 255, 255), CV_FILLED);
    
            double a=contourArea( contours[idx],false);
                        if(a> 575)
    
            {
                rectangle(rgb, rect, Scalar(0, 255, 0), 2);
                y++;
            }
            imshow("Result1",rgb);
        }
        cout<<" The number of elements"<<y<< endl; 
        imshow("Result",mask);
        imwrite(OUTPUT_FOLDER_PATH + string("rgb.jpg"), rgb);
        waitKey(0);
        return 0;
    }
    
    /#包括“stdafx.h”
    #包括
    #包括
    #包括
    #包括
    #包括“tchar.h”
    使用名称空间cv;
    使用名称空间std;
    #定义输入文件“p.jpg”
    #定义输出文件夹路径字符串(“”)
    int _tmain(int argc,_TCHAR*argv[]
    {
    Mat large=imread(输入文件);
    Mat-rgb;
    //减少采样并将其用于处理
    吡咯烷酮(大,rgb);
    垫小;
    CVT颜色(rgb,小,CV_bgr2灰色);
    //形态梯度
    垫梯度;
    Mat morphKernel=getStructuringElement(变形椭圆,大小(2,2));
    Mat morphKernel1=getStructuringElement(变形椭圆,大小(1,1));
    形态学(小,梯度,形态梯度,形态核);
    //二值化
    Mat bw;
    阈值(梯度、bw、5.0、50.0、阈值二元、阈值大津);
    //连接水平方向的区域
    垫子连接;
    morphKernel=getStructuringElement(MORPH_RECT,Size(9,1));
    morphologyEx(bw,连通,MORPH_-CLOSE,morphKernel);
    形态学(bw,连通,形态开放,形态核1);
    morphologyEx(连通,连通,MORPH_CLOSE,morphKernel);
    morphologyEx(连通,连通,MORPH_CLOSE,morphKernel);
    morphologyEx(连通,连通,MORPH_CLOSE,morphKernel);
    //寻找轮廓
    Mat mask=Mat::zeros(bw.size(),CV_8UC1);
    矢量等值线;
    向量层次;
    findContours(连通、轮廓、层次、CV_RETR_CCOMP、CV_CHAIN_近似、简单、点(0,0));
    //过滤轮廓
    int y=0;
    对于(int idx=0;idx>=0;idx=hierarchy[idx][0])
    {
    Rect Rect=boundingRect(等高线[idx]);
    Mat maskROI(蒙版,矩形);
    maskROI=标量(0,0,0);
    //填充轮廓
    绘制等高线(遮罩、等高线、idx、标量(255、255、255)、CV_填充);
    双a=轮廓面积(轮廓[idx],假);
    如果(a>575)
    {
    矩形(rgb,rect,标量(0,255,0),2);
    y++;
    }
    imshow(“结果1”,rgb);
    }
    
    根据图像,似乎总是有4组数字。如果您可以确保图像大部分是水平的,您可以尝试首先水平计数零交叉。它应该在32-64之间。这将允许您水平定位数字的位置。然后执行您现在正在执行的步骤,即使用mor定位斑点它们必须均匀分布。满足这两个条件的元素很少。