Как обнаружить рябь на изображении с OpenCV - PullRequest
3 голосов
/ 03 мая 2019

Итак, у меня есть картинка песчаной дюны, которая выглядит сейчас так:Python.Я только изучаю эту библиотеку, поэтому я не знаю всех причуд в библиотеке.Я провел некоторое исследование, но не смог найти проблему, подобную этой, эта особенно трудна из-за теней, созданных из ряби.Мой ожидаемый результат должен быть несколько противоположен этому, делая все рябь выделяющейся больше, чем другие особенности.Ниже изображение человека с его волосами как особенность, которая выделяется.Я хочу сделать то же самое с рябью в дюне ниже.

image here Следующий код - это то, что у меня ниже, и это вывод моего конечного продукта, но он все еще требует некоторой работы.

 path = "C:/some path//to get//to my picture//Dune field_resize.jpg"


# image I'm using
img = cv2.imread ( path , cv2.IMREAD_GRAYSCALE )
kernel = np.ones ( (5 , 5) , np.uint8 )

# Canny edge detecting
edges = cv2.Canny ( img , 75 , 200 )
th , img = cv2.threshold ( img , 220 , 255 , cv2.THRESH_BINARY_INV );

# Copy the thresholded image.
img_floodfill = img.copy ()

# Mask used to flood filling.
# Notice the size needs to be 2 pixels than the image.
h , w = img.shape[:2]
mask = np.zeros ( (h + 2 , w + 2) , np.uint8 )

# Floodfill from point (0, 0)
cv2.floodFill ( img_floodfill , mask , (0 , 0) , 255 );

# Invert floodfilled image
img_floodfill_inv = cv2.bitwise_not ( img_floodfill )

# Combine the two images to get the foreground.
img_out = img | img_floodfill_inv

# Display images.
cv2.imwrite ( "Thresholded Image.png" , img )
cv2.imwrite ( "Floodfilled Image.png" , img_floodfill )
cv2.imwrite ( "Inverted Floodfilled Image.png" , img_floodfill_inv )
cv2.imwrite ( "Foreground.png" , img )
cv2.waitKey ( 0 )

cv2.imwrite ( "canny_edge.png" , edges )

img_erosion = cv2.erode ( img , kernel , iterations=1 )

cv2.waitKey ( 0 )
cv2.destroyAllWindows ()

enter image here

1 Ответ

4 голосов
/ 04 мая 2019

Вот простой подход с использованием некоторой фильтрации

  • Преобразование изображения в оттенки серого
  • Используйте обнаружение хитрых краев, чтобы найти края
  • Найти контуры
  • Для каждого контура найдите его площадь и отфильтруйте, используя максимальную пороговую площадь

Канне

enter image description here

Обнаруженная рябь

enter image description here

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

import cv2
import numpy as np

original_image = cv2.imread('1.jpg')
gray = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)

canny = cv2.Canny(gray, 50, 150)
cnts = cv2.findContours(canny.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

threshold_max_area = 165
for c in cnts:
    area = cv2.contourArea(c)
    if area < threshold_max_area:
        cv2.drawContours(original_image,[c], 0, (0,255,0), 1)

cv2.imshow('canny', canny)
cv2.imshow('found', original_image)

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