#python #opencv #computer-vision #object-detection #counting
#python #opencv #компьютерное зрение #обнаружение объектов #подсчет
Вопрос:
Я пытаюсь создать общий алгоритм подсчета объектов, используя python и OpenCV (открытый, чтобы попробовать другие методы), однако, похоже, я не могу хорошо рассчитывать различные объекты и не знаю, как приспособиться к этому
https://imgur.com/a/yAkRxWH вот несколько примеров тестовых изображений.
Это для ускорения подсчета запасов небольших объектов.
** РЕДАКТИРОВАТЬ Это мой текущий код (простой детектор больших двоичных объектов)
# 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
Как я могу улучшить этот алгоритм, чтобы получить лучшее обнаружение для общего варианта использования объектов без необходимости изменять параметры каждый раз для каждого объекта?
Комментарии:
1. Покажите ваш код ваш текущий и ожидаемый результат.
Ответ №1:
Вы можете попробовать использовать подход OpenCV, вы могли бы использовать
SimpleBlobDetector
Очевидно, что это тестовое изображение, и полученный мной результат также не идеален, поскольку требуется установить много гиперпараметров. Гиперпараметры делают его довольно гибким, поэтому с него стоит начать.
Это то, что делает детектор (подробнее см. Здесь):
- Пороговое значение: преобразование исходных изображений в несколько двоичных изображений путем порогового значения исходного изображения с пороговыми значениями, начинающимися с минимального порога. Эти пороговые значения увеличиваются на
thresholdStep
untilmaxThreshold
. Итак, первый порог равенminThreshold
, второй равенminThreshold thresholdStep
, третий равенminThreshold 2 x thresholdStep
и так далее. - Группировка: в каждом двоичном изображении соединенные белые пиксели группируются вместе. Давайте назовем эти двоичные двоичные объекты.
-
Слияние: вычисляются центры двоичных двоичных объектов в двоичных изображениях, и двоичные объекты, расположенные ближе, чем
minDistBetweenBlobs
объединяются. -
Вычисление центра и радиуса: вычисляются и возвращаются центры и радиусы новых объединенных больших двоичных объектов.
Найдите код ниже изображения.
# 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. Спасибо за рекомендацию — Похоже, я уже использовал тот же алгоритм для обнаружения больших двоичных объектов и надеялся изменить его, чтобы обеспечить более точное обнаружение для широкого набора объектов без индивидуальной настройки каждый раз
2. @Jack смотрите мой второй ответ
Ответ №2:
Для лучшей читаемости я бы предпочел включить это во второй ответ: вы могли бы использовать подход сегментации, например, алгоритм водораздела
Любое изображение в оттенках серого можно рассматривать как топографическую поверхность, где высокая интенсивность обозначает вершины и холмы, а низкая интенсивность обозначает долины. Вы начинаете заполнять все изолированные долины (локальные минимумы) водой разного цвета (метками). По мере подъема воды, в зависимости от пиков (градиентов) поблизости, вода из разных долин, очевидно, разного цвета, начнет сливаться. Чтобы избежать этого, вы строите барьеры в местах, где сливается вода. Вы продолжаете работу по заполнению водой и строительству барьеров, пока все вершины не окажутся под водой. Затем созданные вами барьеры дают вам результат сегментации. Это «философия» водораздела.