使用OpenCV从UIImage中检测图像对象

4
我完全不了解OpenCV,但在搜索时了解到目标检测和边缘检测。但是,仍然无法找到从屏幕截图中检测图像的正确方法。
例如,如果我传递一个包含照片的图像,如下所示,那么我需要从源图像中提取该照片。

enter image description here

编辑 在跟随@Amitay Nachmani的答案之后,我尝试实现以下代码,直到第4步。

-(UIImage*)processImage:(UIImage*)sourceImage{

    cv::Mat processMat;
    UIImageToMat(sourceImage, processMat);

    cv::Mat grayImage;
    cvtColor(processMat, grayImage, CV_BGR2GRAY);

    cv::Mat cannyImage;
    cv::Canny(grayImage, cannyImage, 0, 50);


    cv::Vec2f lines2;
    std::vector<cv::Vec2f> lines;
    cv::HoughLines(cannyImage, lines, 1, CV_PI/180, 300);

    size_t sizeOfLine = lines.size();
    for(size_t i=0;i<sizeOfLine;i++){
        float rho = lines[i][0], theta = lines[i][1];

        if(rho==0){
            cv::Point pt1,pt2;
            double a = cos(theta), b = sin(theta);
            double x0 = a*rho, y0 = b*rho;
            pt1.x = cvRound(x0 + 1000*(-b));
            pt1.y = cvRound(y0 + 1000*(a));
            pt2.x = cvRound(x0 - 1000*(-b));
            pt2.y = cvRound(y0 - 1000*(a));

            cv::line(cannyImage, pt1, pt2, cv::Scalar(255,0,0),2.0);
        }
    }

    UIImage *result = MatToUIImage(cannyImage);
    return result;
}

从上面的代码中,我得到了以下生成的图像。 输入图像描述 编辑2 我通过将条件if(rho==0)替换为if(theta==0)来修改代码。
这导致下面的图像: 输入图像描述 但是,接下来该怎么做呢? 我在下一步有点困惑。

嘿,Mrug,你找到确切的解决方案了吗? - Salman Ghumsani
我有相同的问题。 - Salman Ghumsani
3个回答

2

截图本身就是源图像。不必与某些预定义的图像匹配。只需提取放置在白色背景或类似背景中的任何图像即可。 - Mrug
好的,我明白了,但是你的截图并没有完全白色的背景,你有文本和链接,它们是你白色背景的一部分。无论如何,我希望你能够根据图片的高对比度区域和白色背景来区分图像,定义一个静态强度阈值。 - uelordi

2
如果你知道图片总是在第二条水平线和第三条水平线之间,那么可以按照以下步骤进行处理:
  1. 将图片转换为灰度图像(opencv cvtColor)
  2. 运行Canny边缘检测算法(opencv Canny())
  3. 使用霍夫变换找到直线(opencv HoughLines() http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_houghlines/py_houghlines.html
  4. 只选择4条最明显的水平线(因为要选择水平线,所以需要设置theta=90)
  5. 根据y坐标对找到的直线进行排序
  6. 将图片裁剪到第二条和第三条线之间

谢谢@Amitay,但是我对这些东西太新了,如果你能提供一些关于上述内容的文档或者一些代码片段之类的东西,我将非常感激。 - Mrug
我编辑了我的问题,并附上第四步的结果图像。但在那之后卡住了,请您提供更多细节,谢谢。 - Mrug
我写错了,应该将 rho = 0 替换为 theta = 90。 - Amitay Nachmani
我认为它是以弧度为单位的,所以尝试使用pi/2。同时将Hugh阈值降低到150。 - Amitay Nachmani
theta = 0 给你垂直线。 - Amitay Nachmani
显示剩余4条评论

2
我完全同意下面的帖子,这是最好的解决方案,但不幸的是,我猜@Mrug的发展将针对智能手机设备,而Canny边缘检测和霍夫线变换在这些平台上计算非常昂贵。
也许您可以使用Sobel导数来计算水平和垂直导数。
以下链接可能会对您有所帮助:
Sobel导数 http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html Canny边缘检测器 http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html 霍夫变换:

http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接