python - 如何在圆形对象周围绘制轮廓并使用 OpenCV Python 找到它的 ROI?
问题描述
我试图在图像中存在的圆形对象上绘制轮廓并找到它的面积和质心。但我没能做到,因为轮廓被绘制在整个图像上,如图所示。我只想在圆形白色物体上绘制轮廓,如图所示。
预期结果:
我只想在图像中显示的这个白色对象上绘制圆形轮廓并显示其质心和面积。OpenCV,忽略其余部分。
下面是附上的代码。
代码:
import cv2
import numpy as np
import imutils
cap = cv2.VideoCapture(0)
cap.set(3,640)
cap.set(4,480)
while True:
_,frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_blue = np.array([90,60,0])
upper_blue = np.array([121,255,255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)
cnts = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts= imutils.grab_contours(cnts)
for c in cnts:
area = cv2.contourArea(c)
if area > 1500:
cv2.drawContours(frame, [c], -1, (0,255,0), 3)
M = cv2.moments(c)
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.circle(frame, (cx, cy), 7, (255, 255, 255), -1)
cv2.putText(frame, "Centre", (cx - 20, cy - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
cv2.imshow("frame", frame)
print("area is ...", area)
print("centroid is at ...", cx, cy)
k=cv2.waitKey(1000)
if k ==27:
break
cap.release()
cv2.destroyAllWindows()
任何帮助,将不胜感激。提前致谢。
解决方案
这可以根据需要以多种方式完成。一种简单的方法可以是:
首先,过滤ROI。所以我们知道三件事,ROI 是白色的,是一个圆圈,我们知道它的大约面积。
对于白色:
def detect_white(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)
return thresh
尽管您需要根据需要使用白色检测算法。白色检测的一些好方法是使用阈值(如上),使用 HSL 颜色空间,因为白度密切依赖于亮度(cv2.cvtColor(img, cv2.COLOR_BGR2HLS
)等。
所以在下面的代码中,我们首先通过白色过滤掉 ROI,然后通过这些白色轮廓的形状和面积。
image = cv2.imread("path/to/your/image")
white_only = detect_white(image)
contours, hierarchy = cv2.findContours(white_only, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
circles = []
for contour in contours:
epsilon = 0.01 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
area = cv2.contourArea(contour)
if len(approx) > 12 and area > 1000 and area < 3000:
circles.append(contour)
# Now the list circles would have all such
# contours satisfying the above conditions
# If len(circles) != 1 or isn't the circle you
# desire, more filtering is required
cv2.drawContours(image, circles, -1, (0, 255, 0), 3)
选择轮廓取决于面积和顶点(由 返回cv2. approxPolyDP()
)。
如您的图像所示,白色大圆圈的面积很大,并且非常接近一个圆圈,我检查了它,例如:len(approx) > 12 and area > 1000 and area < 3000:
。根据您的情况调整此行并告诉我它是否解决了您的问题。如果没有,我们可以讨论一些更好的方法或使用这个方法来使其更准确。
推荐阅读
- javascript - 为数组中的变量分配新值的 forEach 循环不会替换变量的值
- r - 在脚本内的 R 中安装包
- java - JPA 加载实体,但在 @OneToMany 列表中,仅加载特定的
- python - 如何“选择” spaCy 模式匹配的部分,而不是整个匹配?
- java - 如何模拟抽象类的抽象方法?
- css - Bootstrap 3,如何防止 col-md-# 堆叠?
- docker - 单独运行多个 docker-compose 文件
- python - python - 如何在python中的id =“firstheading”之后抓取网页上的所有信息?
- c# - Dotnet CSV Helper 无法解析文件
- javascript - 模拟键盘输入/将字符串插入文本区域(doulingo)