如何仅在外部对象周围创建边界 boxes/contour - Python OpenCV
How can I create bounding boxes/contour around the outer object only - Python OpenCV
所以我一直在尝试围绕我用油漆制作的几个水果制作边界框。我是 opencv 的初学者,所以我看了几个教程和我输入的代码,在对象周围制作轮廓并使用它创建边界框。然而,它会产生太多微小的轮廓和边界框。例如,这里是初始图片:
这是我的代码运行后的图片:
然而这就是我想要的:
这是我的代码:
import cv2
import numpy as np
img = cv2.imread(r'C:\Users\bob\Desktop\coursera\coursera-2021\project2\fruits.png')
grayscaled = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(grayscaled, (7,7), 1)
canny = cv2.Canny(blur, 50, 50)
img1 = img.copy()
all_pics = []
contours, Hierarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02*peri, True)
x, y, w, h = cv2.boundingRect(approx)
bob = img [y:y+h, x:x+w]
all_pics.append((x, bob))
cv2.rectangle(img1, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow("title", img1)
cv2.waitKey(0)
我认为 FloodFill 结合 FindContours 可以帮助你:
import os
import cv2
import numpy as np
# Read original image
dir = os.path.abspath(os.path.dirname(__file__))
im = cv2.imread(dir+'/'+'im.png')
# convert image to Grayscale and Black/White
gry = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite(dir+'/im_1_grayscale.png',gry)
bw=cv2.threshold(gry, 127, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite(dir+'/im_2_black_white.png',bw)
# Use floodfill to identify outer shape of objects
imFlood = bw.copy()
h, w = bw.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
cv2.floodFill(imFlood, mask, (0,0), 0)
cv2.imwrite(dir+'/im_3_floodfill.png',imFlood)
# Combine flood filled image with original objects
imFlood[np.where(bw==0)]=255
cv2.imwrite(dir+'/im_4_mixed_floodfill.png',imFlood)
# Invert output colors
imFlood=~imFlood
cv2.imwrite(dir+'/im_5_inverted_floodfill.png',imFlood)
# Find objects and draw bounding box
cnts, _ = cv2.findContours(imFlood, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for cnt in cnts:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02*peri, True)
x, y, w, h = cv2.boundingRect(approx)
bob = im[y:y+h, x:x+w]
cv2.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 2)
# Save final image
cv2.imwrite(dir+'/im_6_output.png',im)
灰度和black/white:
添加洪水填充:
将原始对象与填充版本混合:
反转混合版的颜色:
最终输出:
他的回答正是我想要的。如果有人遇到这个问题试试这个:
Draw contours around objects with OpenCV
所以我一直在尝试围绕我用油漆制作的几个水果制作边界框。我是 opencv 的初学者,所以我看了几个教程和我输入的代码,在对象周围制作轮廓并使用它创建边界框。然而,它会产生太多微小的轮廓和边界框。例如,这里是初始图片:
这是我的代码运行后的图片:
然而这就是我想要的:
这是我的代码:
import cv2
import numpy as np
img = cv2.imread(r'C:\Users\bob\Desktop\coursera\coursera-2021\project2\fruits.png')
grayscaled = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(grayscaled, (7,7), 1)
canny = cv2.Canny(blur, 50, 50)
img1 = img.copy()
all_pics = []
contours, Hierarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02*peri, True)
x, y, w, h = cv2.boundingRect(approx)
bob = img [y:y+h, x:x+w]
all_pics.append((x, bob))
cv2.rectangle(img1, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow("title", img1)
cv2.waitKey(0)
我认为 FloodFill 结合 FindContours 可以帮助你:
import os
import cv2
import numpy as np
# Read original image
dir = os.path.abspath(os.path.dirname(__file__))
im = cv2.imread(dir+'/'+'im.png')
# convert image to Grayscale and Black/White
gry = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite(dir+'/im_1_grayscale.png',gry)
bw=cv2.threshold(gry, 127, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite(dir+'/im_2_black_white.png',bw)
# Use floodfill to identify outer shape of objects
imFlood = bw.copy()
h, w = bw.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
cv2.floodFill(imFlood, mask, (0,0), 0)
cv2.imwrite(dir+'/im_3_floodfill.png',imFlood)
# Combine flood filled image with original objects
imFlood[np.where(bw==0)]=255
cv2.imwrite(dir+'/im_4_mixed_floodfill.png',imFlood)
# Invert output colors
imFlood=~imFlood
cv2.imwrite(dir+'/im_5_inverted_floodfill.png',imFlood)
# Find objects and draw bounding box
cnts, _ = cv2.findContours(imFlood, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for cnt in cnts:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02*peri, True)
x, y, w, h = cv2.boundingRect(approx)
bob = im[y:y+h, x:x+w]
cv2.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 2)
# Save final image
cv2.imwrite(dir+'/im_6_output.png',im)
灰度和black/white:
添加洪水填充:
将原始对象与填充版本混合:
反转混合版的颜色:
最终输出:
他的回答正是我想要的。如果有人遇到这个问题试试这个: Draw contours around objects with OpenCV