我正在尝试使用python和openCV(可以尝试其他方法)制作通用的对象计数算法,但是我似乎无法很好地了解各种对象,也不知道如何适应那
https://imgur.com/a/yAkRxWH是一些示例测试图像。
这是为了加快较小物品的盘点。
**编辑 这是我当前的代码(简单的Blob检测器)
# Standard imports
import cv2
import numpy as np;
# Read image
im = cv2.imread("./images/screw_simple.jpg", cv2.IMREAD_GRAYSCALE)
im = cv2.resize(im, (1440, 880))
# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()
# Change thresholds
params.minThreshold = 10 #10
params.maxThreshold = 200 #200
# Filter by Area.
params.filterByArea = True # True
params.minArea = 500 #1500
# Filter by Circularity
params.filterByCircularity = True #True
params.minCircularity = 0.1 #0.1
# Filter by Convexity
params.filterByConvexity = True #True
params.minConvexity = 0.0 #0.87
# Filter by Inertia
params.filterByInertia = True #True
params.minInertiaRatio = 0.0 #0.01
# Create a detector with the parameters
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3:
detector = cv2.SimpleBlobDetector(params)
else:
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(im)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures
# the size of the circle corresponds to the size of blob
total_count = 0
for i in keypoints:
total_count = total_count + 1
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show blobs
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)
print(total_count)
这是我得到的结果:https://imgur.com/a/id6OlIA
如何改进该算法以更好地检测对象的一般用例,而不必每次都为每个对象修改参数?
答案 0 :(得分:0)
您可以尝试使用OpenCV方法,也可以使用
SimpleBlobDetector
很明显,这是一个测试图像,我得到的结果也不完美,因为要设置的超参数很多。超参数使它非常灵活,因此它是一个不错的起点。
这就是检测器的功能(请参见详细here):
thresholdStep
直到maxThreshold
。因此,第一个阈值为minThreshold
,第二个阈值为minThreshold + thresholdStep
,第三个阈值为minThreshold + 2 x thresholdStep
,依此类推。 合并:计算二进制图像中二进制blob的中心,并合并比minDistBetweenBlobs
更近的blob。
中心和半径计算:计算并返回新合并的Blob的中心和半径。
找到下面的代码。
# Standard imports
import cv2
import numpy as np
# Read image
im = cv2.imread("petri.png", cv2.IMREAD_COLOR)
# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()
# Change thresholds
params.minThreshold = 0
params.maxThreshold = 255
# Set edge gradient
params.thresholdStep = 5
# Filter by Area.
params.filterByArea = True
params.minArea = 10
# Set up the detector with default parameters.
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(im)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255),
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)
答案 1 :(得分:0)
为了获得更好的可读性,我宁愿再回答一遍:您可以 使用细分方法,例如watershed algorithm
任何灰度图像都可以视为地形图表面,其中高强度表示山峰和丘陵,而低强度表示山谷。您开始用不同颜色的水(标签)填充每个孤立的山谷(局部最小值)。随着水的上升,取决于附近的峰(梯度),来自不同山谷(显然具有不同颜色)的水将开始合并。为了避免这种情况,您可以在水汇合的位置建造障碍。您将继续填充水和建造障碍物的工作,直到所有山峰都在水下。然后,您创建的障碍将为您提供细分结果。这就是分水岭背后的“哲学”。