使用 OpenCV 计算昆虫时的重叠对象问题

APC*_*APC 6 python opencv image-processing counting computer-vision

我正在尝试数一群蟋蟀(昆虫)的数量。我将使用 openCV 库的图像处理方法。当农民出售蟋蟀时,这将提供更准确的练习。这张照片是用智能手机拍摄的。不幸的是,结果并不如预期。由于大多数蟋蟀彼此重叠,我的代码无法将它们分开,从而导致计数不正确。

我应该采用什么方法来解决这个问题?我的代码有问题吗?

蟋蟀图像

这是我的代码。

import cv2
import numpy as np

img = cv2.imread("c1.jpg",1)

roi=img[0:1500,0:1100]  
gray = cv2.cvtColor(roi,cv2.COLOR_BGR2GRAY)
gray_blur=cv2.GaussianBlur(gray,(15,15),0)
thresh = cv2.adaptiveThreshold(gray_blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,11,1)
kernel=np.ones((1,1),np.uint8)
closing=cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel,iterations=10)

result_img=closing.copy()
contours,hierachy=cv2.findContours(result_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
counter=0
for cnt in contours:
    area = cv2.contourArea(cnt)
    if area <  150  :
    #if area<  300 :
        continue
    counter+=1
    ellipse = cv2.fitEllipse(cnt)
    cv2.ellipse(roi,ellipse,(0,255,0),1)
        
  
cv2.putText(roi,"Crickets="+str(counter),(100,70),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),1,cv2.LINE_AA)
cv2.imshow('ImageOfCrickets',roi)
#cv2.imshow('ImageOfGray',gray)
#cv2.imshow('ImageOfGray_blur',gray_blur)
#cv2.imshow('ImageOfThreshold',thresh)
#cv2.imshow('ImageOfMorphology',closing)

print('Crickets = '+ str(counter))     

cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

现在,我使用闭合形态学和轮廓层次结构来实现椭圆形状方法。

Jos*_*e R 3

这是一个选项。使用自适应阈值,执行侵蚀/扩张和高斯模糊,然后进行轮廓,然后按大小和纵横比对其进行过滤,最后找到每个过滤轮廓的质心。

import cv2

# Load the image
img = cv2.imread('insects.jpg')

# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(3,3),2)
# Threshold the grayscale image
thresh = cv2.adaptiveThreshold(gray,300,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,85,-21)

# # Perform morphological operations
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
thresh = cv2.erode(thresh, kernel, iterations=2)
thresh = cv2.dilate(thresh, kernel, iterations=1)
thresh = cv2.GaussianBlur(thresh, (3,3), 1)

# Find contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

print(contours)

# Filter contours by area and aspect ratio
min_area = 500  # minimum area of contour
max_area = 10000  # maximum area of contour
min_aspect_ratio = 0.3  # minimum aspect ratio of contour
max_aspect_ratio = 3  # maximum aspect ratio of contour

filtered_contours = []
for contour in contours:
    area = cv2.contourArea(contour)
    x, y, w, h = cv2.boundingRect(contour)
    aspect_ratio = float(w) / h if h != 0 else 0
    if area >= min_area and area <= max_area and aspect_ratio >= min_aspect_ratio and aspect_ratio <= max_aspect_ratio:
        filtered_contours.append(contour)
        print(contour)

# Compute centers of mass and draw circles for filtered contours
for contour in filtered_contours:
    # Compute moments of the contour
    M = cv2.moments(contour)
    if M['m00'] != 0:
        # Compute center of mass
        cx = int(M['m10'] / M['m00'])
        cy = int(M['m01'] / M['m00'])
        # Draw circle at center of mass
        cv2.circle(img, (cx, cy), 5, (0, 255, 0), -1)


# Show the original image with filtered contours
cv2.drawContours(img, filtered_contours, -1, (0, 0, 255), 2)
cv2.imwrite('Image_contours.jpg', img)
cv2.imshow('Gray', gray)
cv2.imwrite('image_thresholded_preprocessed.jpg', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

另一种选择与此处所做的类似:

这些图像是经过阈值处理的(不是昆虫是白色的),以及带有中心的轮廓(红点)。现实中不是很好,但我能想到的最好的。看起来工作量很大,但解决误报(在空白处)的方法可能是进行第二次处理,取出质心不暗的轮廓。

昆虫的轮廓和质心(红色)

昆虫图像阈值化和预处理

  • 相关 - 尝试使用分水岭算法:/sf/ask/790640161/。我很想将这个问题作为上述问题的重复来结束,但我想首先尊重您为这个问题提供的赏金。 (2认同)