【问题标题】:How to find white bordered rectangle in an image?如何在图像中找到白色边框的矩形?
【发布时间】:2021-11-10 14:09:45
【问题描述】:

我正在尝试获取图像中白边矩形的坐标。传统的方法是找到轮廓来找到图像中存在的所有矩形,但我只想得到某些边框颜色,如下图

如何仅使用 opencv 获取白色边框矩形的坐标? 对此非常有帮助的任何建议,谢谢

编辑:我尝试了guivi使用python给出的建议,如下所示

import cv2
import numpy as np
import random as rng
image = cv2.imread('strawberry.png')
threshold = 100
grayscale= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
canny_output = cv2.Canny(grayscale, threshold, threshold * 2)

ret, thresh= cv2.threshold(grayscale,200,255,cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(canny_output,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
contours_poly = [None]*len(contours)
#boundRect = [None]*len(contours)
boundRect = list()
centers = [None]*len(contours)
radius = [None]*len(contours)
for i, c in enumerate(contours):
    contours_poly[i] = cv2.approxPolyDP(c, 3, True)
    if len(contours_poly[i]) == 4:
        boundRect.append(cv2.boundingRect(contours_poly[i]))
    #boundRect[i] = cv.boundingRect(contours_poly[i])
    #centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])


drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)

print(len(boundRect))
#for i in range(len(contours)):
#    color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
#    cv.drawContours(drawing, contours_poly, i, color)
#    cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \
#      (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)
#cv.circle(drawing, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), color, 2)
for i in range(len(boundRect)):
    if boundRect[i][2]/boundRect[i][3] > 2:
        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
        cv2.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \
            (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)
        print(f'Rectangle X:{boundRect[i][0]}, Y:{boundRect[i][1]}, W:{boundRect[i][2]}, H:{boundRect[i][3]}')

但我在图像中找不到矩形的位置,因为@guivi 使用 c++ 得到了其他 4 个矩形坐标,如下图所示

【问题讨论】:

    标签: python python-3.x opencv image-processing deep-learning


    【解决方案1】:

    你可以根据自己的想法或多或少做:

    1. 加载图片。
    2. 转换为灰度。
    3. 应用一些阈值。
    4. 计算等高线。
    5. 查看轮廓并检查形状。
    6. 分隔矩形并按纵横比过滤。
    7. 你完成了!

    我使用 C++ 来实现这一点,但我相信你可以将它转换为 python。

    Mat image = imread("st.bmp");
    
    if (image.empty())
        return EXIT_FAILURE;
    
    Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
    vector<vector<Point>> contoursgray;
    vector<Vec4i> hierarchygray;
    threshold(gray, gray, 200, 255, cv::THRESH_BINARY_INV);
    findContours(gray, contoursgray, hierarchygray, RETR_TREE, CHAIN_APPROX_NONE);
    // draw contours on the original image
    Mat image_contour_gray = image.clone();
    //drawContours( image_contour_gray, contoursgray, -1, Scalar(0, 255, 0), 2);
    vector<vector<Point>> contoursgray2;
    for (auto points : contoursgray) {
        double peri = cv::arcLength(points, true);
        vector<Point> aprox;
        cv::approxPolyDP(points, aprox, 0.04 * peri, true);
        if (aprox.size() == 4)
        {
            cv::Rect rect = cv::boundingRect(aprox);
            if (rect.width / rect.height > 1.5) {
                std::cout << rect.x << "  " << rect.y << " " << rect.width << " " << rect.height << std::endl;
                contoursgray2.push_back(aprox);                
            }
        }
    }
    if (contoursgray2.size() > 0) {
        drawContours(image_contour_gray, contoursgray2, -1, Scalar(0, 255, 0), 2);
        imshow("Contour detection using gray conversion", image_contour_gray);
    }
    waitKey(0);
    imwrite("gray.jpg", image_contour_gray);
    destroyAllWindows();
    

    这给了我以下图像作为输出:

    它还在命令prom上输出以下矩形(x,y,w,h):

    我已从opencv 网页上获取教程并更改了以下几行:

    contours_poly = [None]*len(contours)
    #boundRect = [None]*len(contours)
    boundRect = list()
    centers = [None]*len(contours)
    radius = [None]*len(contours)
    for i, c in enumerate(contours):
        contours_poly[i] = cv.approxPolyDP(c, 3, True)
        if len(contours_poly[i]) == 4:
            boundRect.append(cv.boundingRect(contours_poly[i]))
        #boundRect[i] = cv.boundingRect(contours_poly[i])
        #centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])
    
    
    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
    
    
    #for i in range(len(contours)):
    #    color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
    #    cv.drawContours(drawing, contours_poly, i, color)
    #    cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \
    #      (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)
    #cv.circle(drawing, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), color, 2)
    for i in range(len(boundRect)):
        if boundRect[i][2]/boundRect[i][3] > 2:
            color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
            cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \
                (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)
            print(f'Rectangle X:{boundRect[i][0]}, Y:{boundRect[i][1]}, W:{boundRect[i][2]}, H:{boundRect[i][3]}')
    

    【讨论】:

    • 嘿,我尝试在 python 中转换您的 c++ 代码,但结果出现错误,请检查代码的更新问题,让我知道我做错了什么
    • @xionxavier OpenCV 教程网页有你的答案。看看这个页面:https://docs.opencv.org/master/da/d0c/tutorial_bounding_rects_circles.html 如果你用你的图像运行它,你会了解这些功能是如何工作的。不同版本的 OpenCV 使用此功能似乎略有不同,因此请确保根据您使用的 OpenCV 版本查看页面的正确版本。
    • 我按照该教程并尝试实现,但我无法获得矩形的坐标请检查stackoverflow.com/q/69206088/16707127
    • @xionxavier 上面的示例显示了矩形角的坐标。你没有得到相同的结果,还是你期待不同的结果?请准确说明什么不适合您,而不是提出一个新问题。
    • 我无法使用 python 程序找到矩形的坐标,我不懂 c++,所以我很难将它转换成 python
    猜你喜欢
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    相关资源
    最近更新 更多