我想用提供的图像中的白菜找到。我已经有一个使用颜色阈值处理的前一个问题的实现,但是它需要我手动输入HSV或RGB值,我需要一种自适应的控制方式,并考虑使用canny edge来查找边缘然后创建一个掩码。
下面是color thesholding的实现,它是canny的理想输出。
# Import the necessary packages
import numpy as np
import argparse
import cv2
import glob
def auto_canny(image, sigma=0.33):
# compute the median of the single channel pixel intensities
v = np.median(image)
# apply automatic Canny edge detection using the computed median
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
# return the edged image
return edged
# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True,
help = "Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
auto = auto_canny(blurred)
cv2.imshow("Image", auto)
cv2.imwrite("newimage1.jpg", auto)
(_, cnts, _) = cv2.findContours(auto.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
if len(cnts) > 0:
# sort the contours and find the largest one -- we
# will assume this contour correspondes to the area
# of my phone
cnt = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)
cv2.imshow("Tracking", image)
cv2.imwrite("newimage2.jpg", image)
cv2.waitKey(0)
cv2.waitKey(0)
结果:
我的思维过程是使用canny来找到边缘然后使用findcontours来获得最大轮廓并创建一个应该是卷心菜的面具。但是,这似乎不起作用,因为canny输出的结果有很多边缘。
我认为在应用canny边缘检测之前我应该做一些预处理,但我不太清楚应用什么技术来预处理。
编辑:
阅读一些建议并尝试了那些我知道如何做的建议,首先我将其转换为HSV并将图像拆分为相应的H,s和v。实施2种方法,结果如下,任何建议如何提高?
# Import the necessary packages
import numpy as np
import argparse
import cv2
import glob
def auto_canny(image, sigma=0.33):
# compute the median of the single channel pixel intensities
v = np.median(image)
# apply automatic Canny edge detection using the computed median
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
# return the edged image
return edged
# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True,
help = "Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Image", image)
newImage = image.copy()
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
blurred = cv2.GaussianBlur(hsv, (3, 3), 0)
#cv2.imshow("HSV image", blurred)
#now to seperate and only extract hue image
h,s,v = cv2.split(blurred)
cv2.imshow("H", h)
#cv2.imshow("S", s)
#cv2.imshow("V", v)
thresh = cv2.adaptiveThreshold(h, 255,
cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 4)
cv2.imshow("adaptive1", thresh)
cv2.imwrite("adaptive1.jpg", thresh)
(_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
auto = auto_canny(h)
cv2.imshow("canny", auto)
cv2.imwrite("canny1.jpg", auto)
(_, cnts2, _) = cv2.findContours(auto.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
if len(cnts) > 0:
# sort the contours and find the largest one -- we
# will assume this contour correspondes to the area
# of my phone
cnt = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)
cv2.imshow("adaptive2", image)
cv2.imwrite("adaptive2.jpg", image)
if len(cnts2) > 0:
# sort the contours and find the largest one -- we
# will assume this contour correspondes to the area
# of my phone
cnt = sorted(cnts2, key = cv2.contourArea, reverse = True)[0]
cv2.drawContours(newImage, [cnt], -1, (0, 255, 0), 2)
cv2.imshow("canny2", newImage)
cv2.imwrite("canny2.jpg", newImage)
cv2.waitKey(0)
自适应:
的Canny:
答案 0 :(得分:3)
您还可以在色彩空间中设置图像的三维直方图,如果您知道目标是场景中的主要对象,则可以在主要颜色空间(聚类)周围设置边界,然后使用该直方图。分段。这很可能是我想要的。
答案 1 :(得分:2)
不要转换为灰度,转换为某些HSV colorspace并尝试将绿色对象分割出来。
使用adaptiveThreshold而非canny,它可以很好地在本地找到最佳边缘水平