如何分割图像中的两个矩形。还要删除多余的投影来提取矩形的坐标。轮廓检测将整个图像显示为圆形,而不是将其分成两个矩形。
请找到输入图片,
detect_shapes.py
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
sd = ShapeDetector()
for c in cnts:
M = cv2.moments(c)
cX = int((M["m10"] / M["m00"]))
cY = int((M["m01"] / M["m00"]))
shape = sd.detect(c)
c = c.astype("float")
#c *= ratio
c = c.astype("int")
cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (255, 0, 0), 2)
cv2.imshow("Image", image)
cv2.waitKey(0)
shapedetector.py
class ShapeDetector:
def __init__(self):
pass
def detect(self, c):
shape = "unidentified"
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
if len(approx) == 3:
shape = "triangle"
elif len(approx) == 4:
print("value of approx", approx)
(x, y, w, h) = cv2.boundingRect(approx)
ar = w / float(h)
print("value of ar",ar)
if (ar >= 0.95 and ar <= 1.05): shape = "Square"
elif (ar <= 5 and ar >= 3): shape = "Obround"
else: shape = "rectangle"
elif len(approx) == 5:
shape = "pentagon"
elif len(approx) == 2:
shape = "line"
print("value of approx", approx)
else:
shape = "circle"
print("value of approx", approx)
return shape
答案 0 :(得分:2)
正如Akhilesh建议的那样,形态OPEN操作将删除连接两个矩形的线。这里有一个优秀的Python教程:https://docs.opencv.org/3.0.0/d9/d61/tutorial_py_morphological_ops.html。使用适用于您的应用程序的最小内核大小,以防止过多的失真。对于测试图像,我使用的内核大小为5.
detect_shapes.py:
import cv2
from shapedetector import ShapeDetector
image = cv2.imread('rectangles.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]
ksize = 5
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (ksize,ksize))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# ~ cnts = cnts[0] if imutils.is_cv2() else cnts[1]
cnts = cnts[1]
sd = ShapeDetector()
for c in cnts:
M = cv2.moments(c)
if M["m00"] != 0: # prevent divide by zero
cX = int((M["m10"] / M["m00"]))
cY = int((M["m01"] / M["m00"]))
shape = sd.detect(c)
c = c.astype("float")
#c *= ratio
c = c.astype("int")
cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (255, 0, 0), 2)
cv2.imshow("Image", image)
cv2.waitKey(0)
shapedetector.py:
import cv2
class ShapeDetector:
def __init__(self):
pass
def detect(self, c):
shape = "unidentified"
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
if len(approx) == 3:
shape = "triangle"
elif len(approx) == 4:
print("value of approx", approx)
(x, y, w, h) = cv2.boundingRect(approx)
ar = w / float(h)
print("value of ar",ar)
if (ar >= 0.95 and ar <= 1.05): shape = "Square"
elif (ar <= 5 and ar >= 3): shape = "Obround"
else: shape = "rectangle"
elif len(approx) == 5:
shape = "pentagon"
elif len(approx) == 2:
shape = "line"
print("value of approx", approx)
else:
shape = "circle"
print("value of approx", approx)
return shape
输出图片: