Лучший способ отделить фрагменты породы в изображении - PullRequest
3 голосов
/ 11 марта 2020

Я пытаюсь сделать программу для расчета распределения по размерам фрагментов породы по изображениям с конвейерной ленты. Я могу добиться этого только путем сегментации изображения и маркировки. К сожалению, мои результаты не являются удовлетворительными, потому что в программе есть проблема с темными пятнами на обломках породы. Эти пятна неправильно распознаются как края фрагментов (например, в левом верхнем углу программа обнаружила множество мелких фрагментов, где на самом деле это всего лишь один большой фрагмент. Кто-нибудь сталкивался с такой проблемой?

То, что я пробовал до сих пор:

  • Детектор краев Canny
  • порог с различными параметрами
  • findContours в opencv
  • резкость / двусторонняя фильтрация
  • meijering, sato, frangi, hessian ridge детекторы от skimage.filters - я не уверен, правильно ли я их использовал - возможно, у кого-то есть больше опыта с этим и он знает, как найти параметры, которые подходят.
  • открытие / закрытие (расширение, размывание) с различными ядрами
  • текущий подход: открытие -> поиск области фона -> поиск области переднего плана -> вычитание фона и области переднего плана -> водораздел.

код для текущего подхода:


import numpy as np
import cv2
from skimage import data, util, filters, color, measure
from skimage.segmentation import watershed, clear_border
import matplotlib.pyplot as plt
from skimage import img_as_ubyte


name = 'cut.png'
img = cv2.imread(name, 0)
img_color_org = cv2.imread(name)

ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel2 = np.ones((2, 2), np.uint8)
kernel3 = np.ones((3, 3), np.uint8)

opening = cv2.morphologyEx(
    thresh, cv2.MORPH_OPEN, kernel2, iterations=1)

sure_bg = cv2.dilate(opening, kernel3, iterations=3)

dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 3)

ret2, sure_fg = cv2.threshold(
    dist_transform, 0.15*dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)

unknown = cv2.subtract(sure_bg, sure_fg)

ret3, markers = cv2.connectedComponents(sure_fg)
markers = markers + 10
markers[unknown == 255] = 0
markers = cv2.watershed(img_color_org, markers)
img_color_org[markers == -1] = [0, 0, 255]

img2 = color.label2rgb(markers, bg_label=0)
cv2.imwrite('img.png', img_color_org)
cv2.waitKey(0)

pure image Исходное изображение

before watershed* 103 1 * Изображение после вычитания фона и до операции водораздела

current algorithm segmentation Водораздел, примененный к исходному изображению

hand-made Segmentation in paint ручная работа сегментация с нужными краями

Original image with better quality Исходное изображение с лучшим качеством

Любая помощь будет принята с благодарностью!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...