Как найти точные края / бинарный порог металлической детали, такой как сверло?

Я новичок в OpenCV и python, так что любезно помогите мне, как 12-класснику. Моя проблема в том, что я хочу определить правильный порог или край сверла для измерения, но то, что я сделал, дает много шума на изображении, из-за чего я не могу найти правильный контур объекта.

Я попытался удалить блики на изображении, затем выполнить выравнивание гистограммы, после чего попробовал адаптивную пороговую обработку.

gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h,s,v=cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))

bgi=cv2.GaussianBlur(gray, (3, 3), 1.0)
rn_gr = cv2.fastNlMeansDenoising(bgi,None,10,7,21)

equ = cv2.equalizeHist(rn_gr)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(rn_gr)

nonSat = s < 40
disk = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))    
nonSat = cv2.erode(nonSat.astype(np.uint8), disk) 
v2 = v.copy()    
v2[nonSat == 0] = 0;  
glare = v2 > 200;
glare = cv2.dilate(glare.astype(np.uint8), disk);
glare = cv2.dilate(glare.astype(np.uint8), disk);    
corrected = cv2.inpaint(img, glare, 5, cv2.INPAINT_NS)
object=corrected[485:1665,225:335]
gray_co=cv2.cvtColor(object, cv2.COLOR_BGR2GRAY)
bgi_co=cv2.GaussianBlur(gray_co, (3, 3), 1.0)
rn_gr_co = cv2.fastNlMeansDenoising(bgi_co,None,10,7,21)
cl2 = clahe.apply(rn_gr_co)

v=np.median(cl2)
lower=int(max(0,(1.0-sigma)*v))
upper=int(min(255,(1.0+sigma)*v))
print(lower,upper)
edged = cv2.Canny(cl2,lower,upper)
th3_o = cv2.adaptiveThreshold(obj,upper,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
        th3_o=~th3_o

#kernel = np.ones((5,5),np.uint8)
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
morph = cv2.morphologyEx(th3_o, cv2.MORPH_GRADIENT, kernel)
closing = cv2.morphologyEx(th3_o, cv2.MORPH_CLOSE, kernel)
opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel)

contours_o, hierarchy = cv2.findContours(th3_o,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt_o in contours_o:
   epsilon = 0.1*cv2.arcLength(cnt_o,True)
   approx = cv2.approxPolyDP(cnt_o,epsilon,True)
   con_o = cv2.drawContours(th3_o, contours_o, -1, (0,255,0), 3)
plt.imshow(con_o)
plt.show()

мой ожидаемый результат должен выглядеть как рис, который я рисую с границами требуемое изображение, но то, что я получение - это что-то вроде этого нежелательного изображения


person hawxeye    schedule 11.07.2019    source источник
comment
Есть два распространенных заблуждения при обработке изображений: 1) обнаружение краев работает. Это не ! Иногда срабатывают бинаризация / следование контуру. 2) алгоритм может угадать, что вы имеете в виду (например, выбрав только те внутренние ребра, которые вам нужны).   -  person Yves Daoust    schedule 13.07.2019
comment
как можно определить внутренние края после бинаризации изображения, как это показано на изображении выше. например, есть алгоритм отсечения, который находит только края соединенного цикла   -  person hawxeye    schedule 14.07.2019
comment
Смотрите заблуждение 2.   -  person Yves Daoust    schedule 14.07.2019
comment
С какой точностью вы пытаетесь измерить кромку? Как узнать истинные размеры сверла? Вы пытаетесь выполнить измерения в соответствии с каким-либо промышленным стандартом? Предполагая, что вы можете достаточно точно определить края изображения, вы столкнетесь с проблемами с оптикой. Даже с использованием задней подсветки, чтобы сделать деталь темной на светлом фоне, диаметр детали будет немного меньше, чем истинный размер.   -  person Rethunk    schedule 01.08.2019
comment
Я пытаюсь достичь точности 1/10 мм. Я рассчитал истинные размеры с помощью штангенциркуля. да, я пытаюсь измерить по промышленному стандарту. Какие проблемы с оптикой? но я думаю, что откалибровал камеру на искажение объектива. что ты посоветуешь?   -  person hawxeye    schedule 02.08.2019


Ответы (1)


Я думаю, вы используете слишком много операций и слишком много думаете о подходе к обнаружению контуров. Вы используете слишком много последовательных операций, не осознавая цели каждого шага. Обычно предварительная обработка изображения выполняется для удаления шума или сглаживания изображений (размытие по Гауссу / медианное / двустороннее). Затем на изображении выполняется своего рода двоичная сегментация для выделения контуров (пороговая обработка, обнаружение краев Canny). Отсюда можно выполнить морфологические преобразования для дальнейшей фильтрации или усиления, например, размывания или расширения. Затем вы можете найти контуры и выполнить дополнительную фильтрацию (площадь контура, близость, соотношение сторон). Для этой проблемы идея состоит в том, чтобы сохранить ее простой стратегическим подходом, чтобы изолировать внешний контур.


Вот потенциальный подход

  • Преобразование изображения в оттенки серого и медианное размытие для удаления шума и сглаживания изображения
  • Пороговое изображение
  • Найдите контуры
import cv2

image = cv2.imread('1.jpg')

blur = cv2.medianBlur(image, 7)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,160,255, cv2.THRESH_BINARY_INV)[1]

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (36, 255, 12), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imwrite('image.png', image)
cv2.waitKey()

person nathancy    schedule 11.07.2019
comment
красивый результат - person lucians; 12.07.2019
comment
Это отвечает на одну часть, а что насчет внутренней диагностики долота. как их можно обнаружить? - person hawxeye; 12.07.2019
comment
Одна из идей состоит в том, чтобы извлечь рентабельность инвестиций сверла, поскольку у нас есть контур, и отсюда можно выполнить определение порогового значения цвета, чтобы выделить более темные области. Затем вы можете использовать обнаружение краев Canny, чтобы найти контуры диагоналей, и использовать дополнительную фильтрацию, такую ​​как площадь контура, чтобы гарантировать, что захватываются только диагонали. Наконец, замаскируйте все обратно на исходное изображение - person nathancy; 12.07.2019
comment
Думаю, я понял вашу точку зрения, я попробую, но если вы покажете мне результат, подобный тому, который вы уже сделали, это будет намного проще. - person hawxeye; 12.07.2019