Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV - How to find rectangle contour of a rectangle with round corner?

Tags:

python

opencv

I'm trying to find the contour of a rectangle object with round corner in a image. I tried HoughLinesP and findContours, but did not achieve the desired result.

results

I want to find the rectangle like this: desired result

Code:

import cv2
import matplotlib.pyplot as plt
import util

image = cv2.imread("./img/findrect0.png", 1)
gray = util.grayImage(image)

edges = cv2.Canny(image, 50, 200)
lines = cv2.HoughLinesP(edges, 1, cv2.cv.CV_PI/180, 50, minLineLength=50, maxLineGap=10)[0]
linesImage = image.copy()
util.drawLines(linesImage, lines, thickness=10)

contoursImage = image.copy()
(contours, hierarchy) = cv2.findContours(gray.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

util.drawContours(contoursImage, contours, thickness=10)

util.showOpenCVImagesGrid([image, edges, linesImage, contoursImage], 2, 2, titles=["original image", "canny image", "lines image", "contours image"])

util:

import cv2
import math
import matplotlib.pyplot as plt

def showOpenCVImagesGrid(images, x, y, titles=None, axis="on"):
    fig = plt.figure()
    i = 1
    for image in images:
        copy = image.copy()
        channel = len(copy.shape)
        cmap = None
        if channel == 2:
            cmap = "gray"
        elif channel == 3:
            copy = cv2.cvtColor(copy, cv2.COLOR_BGR2RGB)
        elif channel == 4:
            copy = cv2.cvtColor(copy, cv2.COLOR_BGRA2RGBA)

        fig.add_subplot(x, y, i)
        if titles is not None:
            plt.title(titles[i-1])
        plt.axis(axis)
        plt.imshow(copy, cmap=cmap)
        i += 1
    plt.show()


def grayImage(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    return gray


def drawLines(image, lines, thickness=1):
    for line in lines:
        # print("line="+str(line))
        cv2.line(image, (line[0], line[1]), (line[2], line[3]),
                (0, 0, 255), thickness)


def drawContours(image, contours, thickness=1):
    i = 0
    for contour in contours:
        cv2.drawContours(image, [contours[i]], i, (0, 255, 0), thickness)
        area = cv2.contourArea(contour)
        i += 1

I'm using Python 2.7.13 and OpenCV 2.4.13.3.

I've been thinking to extend these lines and get intersection points of lines. Finally, I will get four coordinates of rectangle. But if the image is more complex, I don't know how to deal with.

like image 811
tomfriwel Avatar asked Sep 29 '17 09:09

tomfriwel


People also ask

How do you match contours in OpenCV?

OpenCV comes with a function cv. matchShapes() which enables us to compare two shapes, or two contours and returns a metric showing the similarity. The lower the result, the better match it is.

How do you find the OpenCV of a rectangle?

Use the findContours() and contourArea() Function of OpenCV to Detect Rectangles in Images in Python. We can detect a rectangle present in an image using the findContours() function of OpenCV, and we can use the contourArea() function to sort different rectangles according to their area.

How do you find the coordinates of a bounding box on OpenCV?

Simply find the contours of your mask (docs) and then find the bounding rectangle (docs) of the contour. Note here that the bounding boxes will be represented by the four items (x, y, w, h) , where x, y is the top left corner, and w, h are the width and height respectively.


1 Answers

You need to find the bounding rectangle of the found contours.

img = cv2.imread("image.png", -1)

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

binary = cv2.bitwise_not(gray)

(_,contours,_) = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for contour in contours:
    (x,y,w,h) = cv2.boundingRect(contour)
    cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)

result

like image 152
zindarod Avatar answered Sep 17 '22 14:09

zindarod