【问题标题】:How to crop circles (found with Hough Transform) in OpenCV?如何在 OpenCV 中裁剪圆圈(使用 Hough 变换找到)​​?
【发布时间】:2015-10-25 01:00:24
【问题描述】:

我正在使用来自page 的代码。它工作得很好,我得到了一个我正在寻找的圈子。我所有的图像只有 1 个圆圈,我修改了 HoughCircles() 的参数,这样代码只返回 1 个圆圈。

如何裁剪我的原始图像,使新图像只有圆圈(和其中的区域)并将新图像保存为 JPEG 或 PNG 文件?

根据原代码,圆心由下式给出

(cvRound(circles[1][0]), cvRound(circles[1][1]));

半径由下式给出

cvRound(circles[1][2]);

【问题讨论】:

    标签: c++ image opencv crop geometry


    【解决方案1】:

    在 circles=HoughCircles(...) 之后去麦田圈

    if len(circles) == 1:
        x, y, r = circles[0][0]
        print x, y, r
        mask = np.zeros((w0,h0),dtype=np.uint8)
        cv2.circle(mask,(x,y),r,(255,255,255),-1,8,0)
        #cv2.imwrite(argv[2],mask)
        out = img*mask
        white = 255-mask
        cv2.imwrite(argv[2],out+white)
    

    【讨论】:

    • 你从哪里得到 w0 和 h0?
    • w0h0img(或mask)的宽度/高度,即——w0 = img.shape[0]h0 = img.shape[1]
    【解决方案2】:
    HoughCircles(src, circles, CV_HOUGH_GRADIENT, 1, parameter_1, parameter_2, parameter_3, parameter_4, parameter_5);
    
    for (size_t i = 0; i < circles.size(); i++)
    {
        Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
        int radius = cvRound(circles[i][2]);
        circleroi = src(Rect(center.x - radius, coordinate
                        center.y - radius, 
                        radius *2,         
                        radius * 2));       
    }
    

    【讨论】:

      【解决方案3】:

      你应该使用copyTo加上一个蒙版来检索圆圈内的图像部分,然后你可以根据圆圈的边界框进行裁剪。

      你用imwrite保存图片。

      这个小例子应该可以帮助您入门。

      #include "opencv2/opencv.hpp"
      using namespace cv;
      
      int main()
      {
          // Your initial image
          Mat3b img = imread("path_to_image");
      
          // Your Hough circle
          Vec3f circ(100,50,30); // Some dummy values for now
      
          // Draw the mask: white circle on black background
          Mat1b mask(img.size(), uchar(0));
          circle(mask, Point(circ[0], circ[1]), circ[2], Scalar(255), CV_FILLED);
      
          // Compute the bounding box
          Rect bbox(circ[0] - circ[2], circ[1] - circ[2], 2 * circ[2], 2 * circ[2]);
      
          // Create a black image
          Mat3b res(img.size(), Vec3b(0,0,0));
      
          // Copy only the image under the white circle to black image
          img.copyTo(res, mask);
      
          // Crop according to the roi
          res = res(bbox);
      
          // Save the image
          imwrite("filename.png", res);
      
          // Show your result
          imshow("Result", res);
          waitKey();
      
          return 0;
      }
      

      【讨论】:

        【解决方案4】:

        您可以根据圆的坐标在图像上定义一个感兴趣区域 (ROI),然后imwrite 将只保存裁剪部分:

        cv::Rect roi(x, y, w, h); // I let you do the math ;)
        cv::Mat cropped = original(roi);
        cv::imwrite("cropped.png", cropped);
        

        【讨论】:

        • 第一行会返回一个圆圈吗?它似乎是一个矩形区域:(
        • 嗯……图像是矩形的。你不能有一个圆形的图像。如果您愿意,您可以将圆圈外的像素涂成黑色,或者更好地使用 Alpha 通道使它们透明。
        • 好主意,这将起作用。请提供建议。
        • 是否可以提供至少一些示例代码或参考示例?我是 C++ 新手,需要一些帮助
        • 这是一个很棒的学习练习!你为什么不先尝试一下,使用我的提示和一点点试错,如果你真的被卡住了,你可以随时问一个关于 SO 的问题!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        • 2014-01-31
        相关资源
        最近更新 更多