gpt4 book ai didi

python - 检测图像中的多个矩形

转载 作者:行者123 更新时间:2023-12-02 15:09:03 24 4
gpt4 key购买 nike

我试图检测这张图片中的管道数。为此,我使用 OpenCV 和基于 Python 的检测。基于对类似问题的现有答案,我能够提出以下步骤

  • 打开图片
  • 过滤它
  • 应用边缘检测
  • 使用轮廓
  • 检查计数

  • enter image description here

    管道总数为 ~909 当我们手动计算它时,给或取 4。

    应用过滤器后
    import cv2
    import matplotlib.pyplot as plt
    import numpy as np

    img = cv2.imread('images/input-rectpipe-1.jpg')
    blur_hor = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((11,1,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
    blur_vert = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((1,11,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
    mask = ((img[:,:,0]>blur_hor*1.2) | (img[:,:,0]>blur_vert*1.2)).astype(np.uint8)*255

    我得到这个蒙面图像

    enter image description here

    这在显示的可见矩形数量方面看起来相当准确。但是,当我尝试进行计数并在图片顶部绘制边界框时,它也会选择很多不需要的区域。对于圆,HoughCircles 有一种定义最大和最小半径的方法。矩形是否有类似的东西可以提高准确性。另外,我愿意接受有关解决此问题的替代方法的建议。
    ret,thresh = cv2.threshold(mask,127,255,0)
    contours,hierarchy = cv2.findContours(thresh, 1, 2)

    count = 0

    for i in range(len(contours)):

    count = count+1
    x,y,w,h = cv2.boundingRect(contours[i])
    rect = cv2.minAreaRect(contours[i])
    area = cv2.contourArea(contours[i])
    box = cv2.boxPoints(rect)
    ratio = w/h
    M = cv2.moments(contours[i])

    if M["m00"] == 0.0:
    cX = int(M["m10"] / 1 )
    cY = int(M["m01"] / 1 )

    if M["m00"] != 0.0:
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])

    if (area > 50 and area < 220 and hierarchy[0][i][2] < 0 and (ratio > .5 and ratio < 2)):
    #cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
    cv2.circle(img, (cX, cY), 1, (255, 255, 255), -1)
    count = count + 1



    print(count)

    cv2.imshow("m",mask)
    cv2.imshow("f",img)
    cv2.waitKey(0)

    enter image description here

    更新
    基于第二个答案,我已将 c++ 代码转换为 python 代码并获得了更接近的结果,但仍然遗漏了一些明显的矩形。

    enter image description here

    最佳答案

    当然,您可以按区域过滤它们。我拿了你的二进制图像并继续如下工作:

    1- 对您从 findContours 中找到的所有轮廓进行循环

    2- 在循环中检查每个轮廓是否是内部轮廓

    3-从那些内部轮廓中,检查它们的面积,如果面积在可接受的范围内,检查每个轮廓的宽度/高度比,最后如果也很好,将该轮廓视为管道。

    我对你的二值图像做了上面的方法,然后 找到 794 个管道 :

    enter image description here

    (虽然有些框丢失了,您应该更改边缘检测器的参数以在图像中获得更多可分离的框。)

    这是代码(它是c++但很容易转换为python):

    Mat img__1, img__2,img__ = imread("E:/R.jpg", 0);

    threshold(img__, img__1, 128, 255, THRESH_BINARY);

    vector<vector<Point>> contours;
    vector< Vec4i > hierarchy;

    findContours(img__1, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_NONE);

    Mat tmp = Mat::zeros(img__1.size(), CV_8U);
    int k = 0;
    for (size_t i = 0; i < contours.size(); i++)
    {
    double area = contourArea(contours[i]);
    Rect rec = boundingRect(contours[i]);
    float ratio = rec.width / float(rec.height);

    if (area > 50 && area < 220 && hierarchy[i][2]<0 && (ratio > .5 && ratio < 2) ) # hierarchy[i][2]<0 stands for internal contours
    {
    k++;
    drawContours(tmp, contours, i, Scalar(255, 255, 255), -1);
    }
    }
    cout << "k= " << k << "\n";
    imshow("1", img__1);
    imshow("2", tmp);
    waitKey(0);

    关于python - 检测图像中的多个矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59565581/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com