【问题标题】:How to count small seeds in an image with a noisy background如何计算具有嘈杂背景的图像中的小种子
【发布时间】:2021-06-29 02:59:04
【问题描述】:

我有一张番茄种子的图片,图片中的种子数量是32。我正在尝试使用OpenCV 来计算这些种子。图像有一些噪音导致计数错误。

我的方法是计算圆心。一般的想法是阈值,然后从背景像素填充填充以填充背景(填充填充的工作原理类似于照片编辑应用程序中的油漆桶工具),这样您只能看到中心。

这是我的代码:

img = cv2.imread('tomato.jpg', 0)
dst = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
img = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
seed_pt = (25, 25)
fill_color = 0
mask = np.zeros_like(img)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
for th in range(60, 120):
    prev_mask = mask.copy()
    mask = cv2.threshold(img, th, 255, cv2.THRESH_BINARY)[1]
    mask = cv2.floodFill(mask, None, seed_pt, fill_color)[1]
    mask = cv2.bitwise_or(mask, prev_mask)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

n_centers = cv2.connectedComponents(mask)[0] - 1
print('There are %d cells in the image.'%n_centers)

输出是:

图像中有 34 个单元格。

原始计数为 32

我该如何解决这个问题?

【问题讨论】:

  • 这不是小型机器学习项目的一个很好的例子吗?不难,但在不同条件下(光线、噪点、变焦......)可能很稳健。

标签: python python-3.x opencv image-processing opencv3.0


【解决方案1】:

我的解决方案是结合RGB遮罩,HSV遮罩使用inRange,还有一些需要改进的地方,但概念是在多个颜色空间中进行遮罩:

输出:图像中有 32 个单元格。

import cv2
import numpy as np
import matplotlib.pyplot as plt

def HSV_mask(img, hsv_range):
    """
    Function: check_HSV, to get the ratio of the marked pixels of specific color in the frame,
      using HSV space.
    ---
    Parameters:
    @param: img, ndarray, image frame of shape [height, width, 3(BGR)].
    @param: hsv_range, tuple of 6, defines the hsv ranges low high for Hue, Saturation, and Value.
    ---
    @return: mask, ndarray, the masked image for the given color.
    """
    hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

    mask=cv2.inRange(hsv_img,hsv_range[0::2],hsv_range[1::2])

    return mask


img = cv2.imread('001.jpg')

# RGB Mask
rgb_mask = img.copy()
rgb_mask[rgb_mask[...,0]>140]=(0, 0, 0)
rgb_mask[rgb_mask[...,1]>140]=(0, 0, 0)
rgb_mask[rgb_mask[...,2]<70]=(0, 0, 0)
rgb_mask[np.sum(rgb_mask, axis=2)>0]=(1, 1, 1)

masked = img*rgb_mask


# HSV Mask
H1 = (1, 8)
H2 = (175, 180)
S = (40, 255)
V = (100, 150)

myRange1 = (H1 + S + V)
myRange2 = (H2 + S + V)
hsv_mask1 = HSV_mask(masked, myRange1)
hsv_mask2 = HSV_mask(masked, myRange2)
hsv_mask = hsv_mask1#cv2.bitwise_or(hsv_mask1, hsv_mask2)

# Morphology
k = 7
# Get the structuring element:
maxKernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, ksize=(k, k))
# Perform closing:
mask = cv2.morphologyEx(hsv_mask, cv2.MORPH_CLOSE, maxKernel, None, None, 1, cv2.BORDER_CONSTANT)


# Median Filter
filteredMask = cv2.medianBlur(mask,5)

plt.figure(num='Tomato Seeds')

plt.subplot(221)
plt.imshow(img[...,[2, 1, 0]])
plt.title('Original')

plt.subplot(222)
plt.imshow(masked[...,[2,1,0]])
plt.title('rgb masked')

plt.subplot(223)
plt.imshow(hsv_mask)
plt.title('HSV mask')

plt.subplot(224)
plt.imshow(filteredMask)
plt.title('Median Filter')

plt.show()

n_centers = cv2.connectedComponents(filteredMask)[0] - 1
print('There are %d cells in the image.'%n_centers)

【讨论】:

  • 这种情况下种子的数量是多少?
  • @Trilarion 它写在解决方案图像的标题中 32
  • 这适用于这种情况,但对于非常相似的图像,它非常不准确。
  • @vaisxn 当然是的,这个解决方案是针对这个图像的,如果你提供更多的图像,你可能会得到一个更通用的解决方案
  • @Bilal 我明白了。数据集可以在这里找到 --> kaggle.com/jucaguirrear/tomato-seeds
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 2013-04-18
相关资源
最近更新 更多