我正在尝试为这些"斑点"中的每一个设置最小边界框。如下所示。作为图像处理管道的一部分,我使用findContours来检测数据中的轮廓,然后在给定一系列已发现的轮廓的情况下绘制最小边界框。
最小边界框不是很准确 - 有些特征显然是错过的,而其他特征则未能完全覆盖"一个完整的连接功能(而是分成几个小的最小边界框)。我已经玩过检索模式(下面显示的RETR_TREE)和轮廓近似方法(CHAIN_APPROX_TC89_L1如下所示),但找不到我真正喜欢的东西。有人可以提出一个更强大的策略来使用OpenCV Python更准确地捕获这些轮廓吗?
import numpy as np
import cv2
# load image from series of frames
for x in range(1, 20):
convolved = cv2.imread(x.jpg)
original = convolved.copy
#convert to grayscale
gray = cv2.cvtColor(convolved, cv2.COLOR_BGR2GRAY)
#find all contours in given frame, store in array
contours, hierarchy = cv2.findContours(gray,cv2.RETR_TREE, cv2.CHAIN_APPROX_TC89_L1)
boxArea = []
#draw minimum bounding box around each discovered contour
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 2 and area < 100:
rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect)
box = np.int0(box)
cv2.drawContours(original,[box], 0, (128,255,0),1)
boxArea.append(area)
#save box-fitted image
cv2.imwrite('x_boxFitted.jpg', original)
cv2.waitKey(0)
** 编辑:Per Sturkman的建议,绘制所有可能的轮廓似乎涵盖了所有可视检测的功能。
答案 0 :(得分:1)
我知道问题是关于opencv。但是因为我习惯了滑雪,所以这里有一些想法(当然可以在opencv中找到)。
import numpy as np
from matplotlib import pyplot as plt
from skimage import measure
from scipy.ndimage import imread
from skimage import feature
%matplotlib inline
'''
Contour detection using a marching square algorithm.
http://scikit-image.org/docs/dev/auto_examples/plot_contours.html
Not quite sure if this is the best approach since some centers are
biased. Probably, due to some interpolation issue.
'''
image = imread('irregular_blobs.jpg')
contours = measure.find_contours(image,25,
fully_connected='low',
positive_orientation='high')
fig, ax = plt.subplots(ncols=1)
ax.imshow(image,cmap=plt.cm.gray)
for n, c in enumerate(contours):
ax.plot(c[:,1],c[:,0],linewidth=0.5,color='r')
ax.set_ylim(0,250)
ax.set_xlim(0,250)
plt.savefig('skimage_contour.png',dpi=150)
'''
Personally, I would start with some edge detection. For example,
Canny edge detection. Your Image is really nice and it should work.
'''
edges = feature.canny(image, sigma=1.5)
edges = np.asarray(edges)
# create a masked array in order to set the background transparent
m_edges = np.ma.masked_where(edges==0,edges)
fig,ax = plt.subplots()
ax.imshow(image,cmap=plt.cm.gray,alpha=0.25)
ax.imshow(m_edges,cmap=plt.cm.jet_r)
plt.savefig('skimage_canny_overlay.png',dpi=150)
实质上,没有“最佳方法”。例如,边缘检测非常好地检测位置,一些结构保持打开状态。另一方面,轮廓查找产生封闭结构,但中心偏向,您必须尝试使用参数。如果您的图像有一些令人不安的背景,您可以使用扩张来减去背景。 Here是如何进行扩张的一些信息。有时,结账操作也很有用。
从您发布的图片中,您的阈值似乎太高或背景太嘈杂。降低阈值和/或扩张可能会有所帮助。
答案 1 :(得分:0)
正如Moritz所建议的那样,尝试使用SimpleBlobDetector。
是个好主意使用不同的选项,您可能会找到适合您问题的设置。