Извлечь уже известную форму из изображения - PullRequest
1 голос
/ 30 мая 2020

Пытаюсь извлечь этот кусок

enter image description here

From this

enter image description here

Ive tried to detect shapes, no way, train an haarscascade...(Idont have negatives) no way, .... the position can vary (not all of them are inserted) and the angle is not the same.. I cannot crop one by one :-(

Any suggestion ??? Thanks in advance

PS Original image is here https://pasteboard.co/JaTSoJF.png (извините> 2Мб)

После работы над @ganeshtata мы получили

import cv2
import numpy as np
img = cv2.imread('cropsmall.png')
height, width = img.shape[:2]
green_channel = img[:,0:] # Blue channel extraction
res = cv2.fastNlMeansDenoising(green_channel, None, 3, 7, 21) # Non-local means denoising
cv2.imshow('denoised',res)
edges = cv2.Canny(res, 11, 11, 3) # Edge detection
kernel = np.ones((30, 30),np.uint8)
closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # Morphological closing
im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Find all contours in the image

for cnt in contours: # Iterate through all contours
    x, y, w, h = cv2.boundingRect(cnt) # Reject contours whose height is less than half the image height
    if h < height / 2:
        continue
    y = 0 # Assuming that all shapes start from the top of the image
    cv2.rectangle(img, (x, y), \
          (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow('IMG',img)
    cv2.imwrite("test.jpg",img)
    cv2.waitKey(0)

Это дает нам

введите описание изображения здесь

Неплохо ...

1 Ответ

2 голосов
/ 31 мая 2020

Я использовал следующий подход, чтобы извлечь шаблон, указанный в вопросе.

  1. Считайте изображение и извлеките синий канал из изображения.

    import cv2
    import numpy as np
    img = cv2.imread('image.png') 
    height, width = img.shape[:2]
    blue_channel = img[:,:,0]
    

    Синий канал - enter image description here

  2. Примените OpenCV алгоритм устранения шума нелокальных средств * на синем изображении канала. Это гарантирует сглаживание большей части случайного шума в изображении.

    res = cv2.fastNlMeansDenoising(blue_channel, None, 3, 7, 21)
    

    Изображение с уменьшенным шумом - enter image description here

  3. Применить определение края Canny.

    edges = cv2.Canny(res, 1, 10, 3)
    

    Вывод края - enter image description here

  4. Примените Морпологическое закрытие , чтобы попытаться закрыть небольшие зазоры / дыры в изображении.

    kernel = np.ones((30, 30),np.uint8)
    closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
    

    Изображение после применения морфологического закрытия - enter image description here

  5. Найдите все контуры на изображении с помощью cv2.findContours . После нахождения всех контуров мы можем определить ограничивающую рамку каждого контура, используя cv2.boundingRect .

    im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Find all contours
    
    for cnt in contours: # Iterate through all contours
        x, y, w, h = cv2.boundingRect(cnt) $ Get contour bounding box
        if h < height / 2: # Reject contours whose height is less than half the image height
            continue
        y = 0  # Assuming that all shapes start from the top of the image
        cv2.rectangle(img, (x, y), \
              (x + w, y + h), (0, 255, 0), 2)
    
  6. Конечный результат - enter image description here

Полный код -

import cv2
import numpy as np
img = cv2.imread('image.png')
height, width = img.shape[:2]
blue_channel = img[:,:,0] # Blue channel extraction
res = cv2.fastNlMeansDenoising(blue_channel, None, 3, 7, 21) # Non-local means denoising
edges = cv2.Canny(res, 1, 10, 3) # Edge detection
kernel = np.ones((30, 30),np.uint8)
closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # Morphological closing
im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Find all contours in the image

for cnt in contours: # Iterate through all contours
    x, y, w, h = cv2.boundingRect(cnt) # Reject contours whose height is less than half the image height
    if h < height / 2:
        continue
    y = 0 # Assuming that all shapes start from the top of the image
    cv2.rectangle(img, (x, y), \
          (x + w, y + h), (0, 255, 0), 2)

Примечание. Этот подход работает для опубликованного вами образца изображения. Он может / не может быть обобщен для всех изображений.

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