我用OpenCV解决了你的问题
[分水岭](http://docs.opencv.org/3.1.0/d7/d1b/groupuu imgprocuu misc.htmlga3267243e4d3f95165d55a618c65ac6e1
“分水岭”算法。你可以找到分水岭的理论和例子
这里.
首先,我选择了几个点(标记)来指示对象I的位置
想保留,背景在哪里。此步骤是手动的,可以改变
从一张图片到另一张图片。而且,它需要一些重复,直到你得到正确的答案
期望的结果。我建议使用一个工具来获得像素坐标。然后我
创建了一个零的空整数数组,大小与汽车图像相同。以及
然后我将一些值(1:background,[255192128,64]:caru parts)赋给
标记位置的像素。
注意:当我下载你的图片时,我不得不裁剪它以得到一个
那辆车。裁剪后,图像的大小为400x601。这可能不是什么
你拥有的图像的大小,所以标记将被关闭。
之后我使用了分水岭算法。第一个输入是图像,第二个输入是
输入是标记图像(除标记位置外,所有位置均为零)。这个
结果如下图所示。
我将值大于1的所有像素设置为255(汽车),其余的设置为255
(背景)归零。然后我用一个3x3的内核将得到的图像放大到
避免丢失有关汽车轮廓的信息。最后,我用了
放大图像作为原始图像的遮罩,使用cv2.bitwise和()函数,
这是我的密码:
import cv2import numpy as npimport matplotlib.pyplot as plt# Load the imageimg = cv2.imread("/path/to/image.png", 3)# Create a blank image of zeros (same dimension as img)# It should be grayscale (1 color channel)marker = np.zeros_like(img[:,:,0]).astype(np.int32)# This step is manual. The goal is to find the points# which create the result we want. I suggest using a# tool to get the pixel coordinates.# Dictate the background and set the markers to 1marker[204][95] = 1marker[240][137] = 1marker[245][444] = 1marker[260][427] = 1marker[257][378] = 1marker[217][466] = 1# Dictate the area of interest# I used different values for each part of the car (for visibility)marker[235][370] = 255 # car bodymarker[135][294] = 64 # rooftopmarker[190][454] = 64 # rear lightmarker[167][458] = 64 # rear wingmarker[205][103] = 128 # front bumper# rear bumpermarker[225][456] = 128marker[224][461] = 128marker[216][461] = 128# front wheelmarker[225][189] = 192marker[240][147] = 192# rear wheelmarker[258][409] = 192marker[257][391] = 192marker[254][421] = 192# Now we have set the markers, we use the watershed# algorithm to generate a marked imagemarked = cv2.watershed(img, marker)# Plot this one. If it does what we want, proceed;# otherwise edit your markers and repeatplt.imshow(marked, cmap='gray')plt.show()# Make the background black, and what we want to keep whitemarked[marked == 1] = 0marked[marked > 1] = 255# Use a kernel to dilate the image, to not lose any detail on the outline# I used a kernel of 3x3 pixelskernel = np.ones((3,3),np.uint8)dilation = cv2.dilate(marked.astype(np.float32), kernel, iterations = 1)# Plot again to check whether the dilation is according to our needs# If not, repeat by using a smaller/bigger kernel, or more/less iterationsplt.imshow(dilation, cmap='gray')plt.show()# Now apply the mask we created on the initial imagefinal_img = cv2.bitwise_and(img, img, mask=dilation.astype(np.uint8))# cv2.imread reads the image as BGR, but matplotlib uses RGB# BGR to RGB so we can plot the image with accurate colorsb, g, r = cv2.split(final_img)final_img = cv2.merge([r, g, b])# Plot the final resultplt.imshow(final_img)plt.show()
如果你有很多图像,你可能需要创建一个工具来
以图形方式注释标记,甚至是一种查找标记的算法
自动地。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)