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.
I want to find the rectangle like this:
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.
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.
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With