简体   繁体   English

OpenCV / Python-从灰度图像中找到灰度图案矩形的角坐标?

[英]OpenCV/Python - Find corner coordinates of a greyscale patterned rectange from a grey scale image?

I would like to have the coordinates of the corners of a rectangle object from a greyscale image with some noise. 我想从带有一些噪声的灰度图像中获取矩形对象的角坐标。

I start with this image https://imgur.com/BNoCn1u . 我从这张图片开始https://imgur.com/BNoCn1u The central region has a checkered rectangle with different grey intensities. 中心区域具有灰色强度不同的方格矩形。 What i want is coordinates of the rectangle in green https://imgur.com/97efZlb . 我想要的是绿色https://imgur.com/97efZlb矩形的坐标。

With below code: 使用以下代码:

im = cv2.imread("opencv_frame_0.tif",0)
data = np.array(im)
edg = cv2.Canny(data, 120, 255)
ret,thresh = cv2.threshold(data,140,255,1)
imshow(thresh,interpolation='none', cmap=cm.gray)

I am able to get https://imgur.com/1xurVTB . 我能够获得https://imgur.com/1xurVTB Which looks quite good but I don't know how to efficiently get the corner coordinates central white frame. 看起来不错,但是我不知道如何有效地获取拐角坐标的中心白框。 I will have other images like this later where the central grey rectangle can be of a different size so I want the code to be optimized to work for that future. 稍后我将有其他类似的图像,其中中心的灰色矩形可以具有不同的大小,因此我希望对代码进行优化以适合将来。

I tried other examples from OpenCV - How to find rectangle contour of a rectangle with round corner? 我尝试了来自OpenCV的其他示例-如何找到带有圆角的矩形的矩形轮廓? and OpenCV/Python: cv2.minAreaRect won't return a rotated rectangle . OpenCV / Python:cv2.minAreaRect不会返回旋转后的矩形 The last one gives me https://imgur.com/E4Gl8Z6 with best settings. 最后一个给我https://imgur.com/E4Gl8Z6最佳设置。

Any help is appreciated! 任何帮助表示赞赏! Thanks. 谢谢。

If you are looking for python code to achieve a lot more, you can find it at this repo... 如果您正在寻找实现更多功能的python代码,可以在此仓库中找到它。

https://github.com/DevashishPrasad/Angle-Distance https://github.com/DevashishPrasad/Angle-Distance

So, to solve your problem this code might be helpful - 因此,要解决您的问题,此代码可能会有所帮助-

# import the necessary packages
from imutils import perspective
from imutils import contours
import numpy as np
import imutils
import cv2

# load the image, convert it to grayscale, and blur it slightly
image = cv2.imread("test.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)

# perform edge detection, then perform a dilation + erosion to
# close gaps in between object edges
edged = cv2.Canny(gray, 50, 100)
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)

# find contours in the edge map
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

# loop over the contours individually
for c in cnts:
    # This is to ignore that small hair countour which is not big enough
    if cv2.contourArea(c) < 1000:
        continue

    # compute the rotated bounding box of the contour
    box = cv2.minAreaRect(c)
    box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
    box = np.array(box, dtype="int")

    # order the points in the contour such that they appear
    # in top-left, top-right, bottom-right, and bottom-left
    # order, then draw the outline of the rotated bounding
    # box
    box = perspective.order_points(box)
    # draw the contours on the image
    orig = image.copy()
    cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 5)

    # loop over the original points
    for (xA, yA) in list(box):
        # draw circles corresponding to the current points and
        cv2.circle(orig, (int(xA), int(yA)), 9, (0,0,255), -1)
        cv2.putText(orig, "({},{})".format(xA, yA), (int(xA - 50), int(yA - 10) - 20),
            cv2.FONT_HERSHEY_SIMPLEX, 1.8, (255,0,0), 5)

        # show the output image, resize it as per your requirements
        cv2.imshow("Image", cv2.resize(orig,(800,600))) 

    cv2.waitKey(0)

Comments explain it all 评论说明了一切

Output - 输出- 4个角及其坐标

From pre-processing, I get the following output: 从预处理中,我得到以下输出: 在此处输入图片说明 From here you can easily find the 4 corners anyway you like (using things like HarrisCorners, vectorizing the image and taking a geometrical approach, your own corner detection algorithm, etc.). 从这里您可以轻松找到自己喜欢的4个角(使用HarrisCorners等功能,对图像进行矢量化并采用几何方法,您自己的角检测算法等)。 It really depends on your own needs. 这确实取决于您自己的需求。

Here's my code, all I'm doing is: 1. Blur 2. Threshold 3. Find connected components 4. Find the biggest one and separating it 5. Finding the contour 这是我的代码,我要做的是:1.模糊2.阈值3.找到连接的组件4.找到最大的组件并将其分离5.找到轮廓

please modify as needed , take this only as a reference (just in case, OpenCV is the same in C++ and Python, and the examples you provide show that you know what you're doing): 根据需要进行修改 ,仅作为参考(以防万一,OpenCV在C ++和Python中是相同的,并且您提供的示例表明您知道自己在做什么):

#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
    Mat img2, img = imread("pic.png");
    cvtColor(img, img, cv::COLOR_BGR2GRAY);
    blur(img, img, Size(7, 7));

    threshold(img, img2, 0, 255, THRESH_OTSU | THRESH_BINARY_INV);

    Mat labels, stats, centroids;
    int n = cv::connectedComponentsWithStats(img2, labels, stats, centroids, 8, CV_16U);
    ushort area, x0, y0, labelBig = 0, maxArea = 0;
    for (int i = 1 ; i < n ; i++) {
        area = stats.at<int>(i, cv::CC_STAT_AREA);
        if (area > maxArea) {
            maxArea = area;
            labelBig = i;
        }
    }

    Mat img3 = Mat(img2.rows, img2.cols, CV_8U, Scalar(0));

    std::mutex mtx;
    labels.forEach<ushort>([&img3, labelBig, &mtx](ushort &label, const int pos[]) -> void {
        if (label == labelBig) {
            lock_guard<mutex> guard(mtx);
            img3.at<uchar>(pos) = 255;
        }
    });
    Mat img4;
    Canny(img3, img4, 50, 100, 3);
    imshow("Frame", img4);
    waitKey();
    return 0;
}

Notice that I'm using Otsu thresholding which gives it a bit of robustness. 请注意,我正在使用Otsu阈值处理,这使其具有一定的鲁棒性。 Also notice that I'm inverting your image as well; 还请注意,我也在反转您的图像; after that the biggest and whitest area is what I consider your rectangle. 之后,最大和最白的区域就是我认为的矩形。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM