如何找到这四个正方形的外角坐标? (如果旋转图像,形态的关闭/打开不会保留正方形) [英] How to find the coordinates of the outside corners of these 4 squares? (morphological closing/opening does not conserve squares if image is rotated)

查看:178
本文介绍了如何找到这四个正方形的外角坐标? (如果旋转图像,形态的关闭/打开不会保留正方形)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写的工具中的第一个处理步骤之一是查找4个大黑色正方形的外角的坐标。然后将它们用于进行单应变换,以对图像进行偏斜/不旋转(也称为透视变换),最终获得矩形图像。这是一个旋转且嘈杂的输入示例(



仅保留大方块, m使用



形态转换后的输出:





问题:输出正方形不再是正方形,因此正方形左上角的坐标将是完全不精确



我可以减小内核的大小,但是这样可以保留更多不需要的小元素。



问题:如何更好地检测正方形的角?






注意:




  • 作为



    然后

      img = cv2.erode(img,内核,迭代次数= 1)

    给予





    那就不行了!



解决方案

请参见


One of the first processing steps in a tool I'm coding is to find the coordinates of the outside corners of 4 big black squares. They will then be used to do a homographic transform, in order to deskew / unrotate the image (a.k.a perspective transform), to finally get a rectangular image. Here is an example of - rotated and noisy - input (download link here):

To keep the big squares only, I'm using morphological transformations like closing/opening:

import cv2, numpy as np
img = cv2.imread('rotatednoisy-cropped.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((30, 30), np.uint8)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imwrite('output.png', img)

Input file (download link):

Output, after morphological transform:

Problem: the output squares are not square anymore, and therefore the coordinates of the top left corner of the square will be not precise at all!

I could reduce the kernel size, but then it would keep more unwanted small elements.

Question: how to get a better detection of the corners of the squares?


Note:

  • As a morphological closing is just a dilatation + an erosion, I found the culprit:

    import cv2, numpy as np
    img = cv2.imread('rotatednoisy-cropped.png', cv2.IMREAD_GRAYSCALE)
    kernel = np.ones((30, 30), np.uint8)
    img = cv2.dilate(img, kernel, iterations = 1)
    

    After this step, it's still ok:

    Then

    img = cv2.erode(img, kernel, iterations = 1)
    

    gives

    and it's not ok anymore!

解决方案

See this link for detailed explanation on how to de-skew an image.

import cv2
import numpy as np

def corners(box):
    cx,cy,w,h,angle = box[0][0],box[0][1],box[1][0],box[1][1],box[2]
    CV_PI = 22./7.
    _angle = angle*CV_PI/180.;
    b = np.cos(_angle)*0.5;
    a = np.sin(_angle)*0.5;

    pt = []
    pt.append((int(cx - a*h - b*w),int(cy + b*h - a*w)));
    pt.append((int(cx + a*h - b*w),int(cy - b*h - a*w)));
    pt.append((int(2*cx - pt[0][0]),int(2*cy - pt[0][1])));
    pt.append((int(2*cx - pt[1][0]),int(2*cy - pt[1][1])));
    return pt

if __name__ == '__main__':

    image = cv2.imread('image.jpg',cv2.IMREAD_UNCHANGED)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    n = 3
    sigma = 0.3 * (n/2 - 1) + 0.8
    gray = cv2.GaussianBlur(gray, ksize=(n,n), sigmaX=sigma)

    ret,binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY)

    _,contours,_ = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    contours.sort(key=lambda x: len(x), reverse=True)

    points = []
    for i in range(0,4):
        shape = cv2.approxPolyDP(contours[i], 0.05*cv2.arcLength(contours[i],True), True)
        if len(shape) == 4:
            points.append(shape)

    points = np.array(points,dtype=np.int32)
    points = np.reshape(points, (-1,2))
    box = cv2.minAreaRect(points)
    pt = corners(box)

    for i in range(0,4):
       image = cv2.line(image, (pt[i][0],pt[i][1]), (pt[(i+1)%4][0],pt[(i+1)%4][1]), (0,0,255))


    (h,w) = image.shape[:2]
    (center) = (w//2,h//2)
    angle = box[2]

    if angle < -45:
        angle = (angle+90)
    else:
        angle = -angle

    M = cv2.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv2.warpAffine(image, M, (w,h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT)

    cv2.imshow('image', image)
    cv2.imshow('rotated', rotated)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

这篇关于如何找到这四个正方形的外角坐标? (如果旋转图像,形态的关闭/打开不会保留正方形)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆