无法找到并绘制最大的轮廓
Unable to find and draw biggest contour
我想在这个框架上找到并绘制最大的轮廓。
我能找到轮廓。但是当我试图找到最大的轮廓时,它在框架上显示一个小轮廓作为最大的框架。当我只画轮廓时,我可以清楚地看到物体周围有一个很大的轮廓
这是我的尝试:
import cv2
import numpy as np
#capture.release()
cv2.destroyAllWindows()
capture = cv2.VideoCapture(1)
panel = np.zeros([100, 700], np.uint8)
cv2.namedWindow('panel')
def nothing(x):
pass
#some code about trackbar and panel here
while(True):
ret, frame = capture.read()
#some code about trackbar and panel here
roi = frame[s_r: e_r, s_c: e_c]
roi = cv2.GaussianBlur(roi, (5, 5), 0) #sigma = 0
hsv = cv2.cvtColor( roi, cv2.COLOR_RGB2HSV)
#some code about trackbar and panel here
mask = cv2.inRange(hsv, lower_green, upper_green)
mask_inv = cv2.bitwise_not(mask)
bg = cv2.bitwise_and( roi, roi, mask=mask)
fg = cv2.bitwise_and( roi, roi, mask=mask_inv)
gray = cv2.cvtColor(fg, cv2.COLOR_BGR2GRAY)
contours, hierarchy = cv2.findContours(gray,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
max_area = 0
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
area = max_area
x,y,w,h = cv2.boundingRect(contour)
cv2.rectangle(fg,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('bg', bg)
cv2.imshow('fg', fg)
cv2.imshow('panel', panel)
if cv2.waitKey(30) == 27: #siradaki frame'e gecmeden once 30 ms bekle
break
capture.release()
cv2.destroyAllWindows()
Python/OpenCV 解决方案:
在你对等高线的循环中,只需自己找到该等高线的最大区域和相应的 boundingRect。
max_area = 0
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
area = max_area
x,y,w,h = cv2.boundingRect(contour)
或者,如果与您的图像相关,只需获取外部轮廓(大概只有一个)。 (以后请出示您输入的图片)。
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
这个方法似乎对我 Python/OpenCV 有效。我做了一个简单的阈值。然后使用形态学平滑并填充一些。然后我得到轮廓并过滤区域。然后我在图像上绘制轮廓。注意它对形态核的大小很敏感,至少需要10或11。但是如果你让它太大,它会改变区域的形状。
输入:
import cv2
import numpy as np
# load image
img = cv2.imread("green_and_red_regions.png")
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold image
thresh = cv2.threshold(gray,4,255,0)[1]
# apply morphology open to smooth the outline
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# find contours
cntrs = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
# Contour filtering to get largest area
area_thresh = 0
for c in cntrs:
area = cv2.contourArea(c)
if area > area_thresh:
area = area_thresh
big_contour = c
# draw the contour on a copy of the input image
results = img.copy()
cv2.drawContours(results,[big_contour],0,(0,0,255),2)
# write result to disk
cv2.imwrite("greengreen_and_red_regions_threshold.png", thresh)
cv2.imwrite("green_and_red_regions_big_contour.png", results)
cv2.imshow("THRESH", thresh)
cv2.imshow("RESULTS", results)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值和平滑图像:
输入时绘制的等高线轮廓:
我想在这个框架上找到并绘制最大的轮廓。
我能找到轮廓。但是当我试图找到最大的轮廓时,它在框架上显示一个小轮廓作为最大的框架。当我只画轮廓时,我可以清楚地看到物体周围有一个很大的轮廓
这是我的尝试:
import cv2
import numpy as np
#capture.release()
cv2.destroyAllWindows()
capture = cv2.VideoCapture(1)
panel = np.zeros([100, 700], np.uint8)
cv2.namedWindow('panel')
def nothing(x):
pass
#some code about trackbar and panel here
while(True):
ret, frame = capture.read()
#some code about trackbar and panel here
roi = frame[s_r: e_r, s_c: e_c]
roi = cv2.GaussianBlur(roi, (5, 5), 0) #sigma = 0
hsv = cv2.cvtColor( roi, cv2.COLOR_RGB2HSV)
#some code about trackbar and panel here
mask = cv2.inRange(hsv, lower_green, upper_green)
mask_inv = cv2.bitwise_not(mask)
bg = cv2.bitwise_and( roi, roi, mask=mask)
fg = cv2.bitwise_and( roi, roi, mask=mask_inv)
gray = cv2.cvtColor(fg, cv2.COLOR_BGR2GRAY)
contours, hierarchy = cv2.findContours(gray,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
max_area = 0
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
area = max_area
x,y,w,h = cv2.boundingRect(contour)
cv2.rectangle(fg,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('bg', bg)
cv2.imshow('fg', fg)
cv2.imshow('panel', panel)
if cv2.waitKey(30) == 27: #siradaki frame'e gecmeden once 30 ms bekle
break
capture.release()
cv2.destroyAllWindows()
Python/OpenCV 解决方案:
在你对等高线的循环中,只需自己找到该等高线的最大区域和相应的 boundingRect。
max_area = 0
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
area = max_area
x,y,w,h = cv2.boundingRect(contour)
或者,如果与您的图像相关,只需获取外部轮廓(大概只有一个)。 (以后请出示您输入的图片)。
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
这个方法似乎对我 Python/OpenCV 有效。我做了一个简单的阈值。然后使用形态学平滑并填充一些。然后我得到轮廓并过滤区域。然后我在图像上绘制轮廓。注意它对形态核的大小很敏感,至少需要10或11。但是如果你让它太大,它会改变区域的形状。
输入:
import cv2
import numpy as np
# load image
img = cv2.imread("green_and_red_regions.png")
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold image
thresh = cv2.threshold(gray,4,255,0)[1]
# apply morphology open to smooth the outline
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# find contours
cntrs = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
# Contour filtering to get largest area
area_thresh = 0
for c in cntrs:
area = cv2.contourArea(c)
if area > area_thresh:
area = area_thresh
big_contour = c
# draw the contour on a copy of the input image
results = img.copy()
cv2.drawContours(results,[big_contour],0,(0,0,255),2)
# write result to disk
cv2.imwrite("greengreen_and_red_regions_threshold.png", thresh)
cv2.imwrite("green_and_red_regions_big_contour.png", results)
cv2.imshow("THRESH", thresh)
cv2.imshow("RESULTS", results)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值和平滑图像:
输入时绘制的等高线轮廓: