OpenCV: обнаружение ограничивающей рамки, закрывающей метку

#opencv #image-processing #pattern-matching #vision

#opencv #обработка изображений #сопоставление с образцом #миссия

Вопрос:

У меня есть похожие изображения с похожим фоновым шумом. Используя OpenCV, есть ли способ определить область (определить контуры) области, покрывающей метку. Или, по крайней мере, возможно ли обнаружить «грубую» ограничительную рамку, закрывающую область метки?

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

Комментарии:

1. Как насчет использования более высокого порога, а затем нахождения самого большого подключенного компонента ?.

2. не могли бы вы, пожалуйста, уточнить, вы хотите найти похожие надписи на разных фотографиях? или вы хотите просто выбрать надпись самостоятельно и удалить фон?

3. Я хочу выбрать метку и удалить фон. Как только я извлеку область, содержащую метку, я могу запустить ее с помощью SURF / SIFT, чтобы найти похожее изображение. У меня уже есть вторая часть , просто из — за фонового шума мой процент попаданий слишком низок

4. Хем, почему бы тебе не обрезать изображение вручную ?

5. Для этого изображения бинаризация выполняется плавно.

Ответ №1:

Я попытался выполнить эту задачу, основная проблема, которая, вероятно, не позволит обобщить этот алгоритм, заключается в том, как выбрать правильный контур. У меня есть два значения (длины контура) 3108 и 2855. Вы можете попытаться извлечь все ваши фотографии (если они находятся на одинаковом расстоянии от камеры) и установить пороговое значение для желаемого контура между 3050 и 2750, но нет гарантии, что это сработает. Итак, вот как я удаляю фон (полный код):

 import cv2 
import numpy as np


image=cv2.imread('C:/Users/srlatch/Desktop/of8cA.png')
img = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

def clear_vertical(img, target):
    for i in range(img.shape[1]):
        for j in range(img.shape[0]):
            if img[j][i]:
                break
            else:
                target[j][i]=[0,0,0]

def clear_horizontal(img, target):
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if img[i][j]:
                break
            else:
                target[i][j]=[0,0,0]



def turn_off(img):
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            img[i][j]=0

def turn_on(img,result):
    for i in result:
       img[i[0][1]][i[0][0]]=255


def f(list):
    max=[]
    for i in list:
        if len(i)>len(max):
            max=i
    return max 

def rem(ls, thresh):
    new_c=[]
    for i in ls:
        if len(i)>thresh:
            new_c.append(i)
    return new_c 

def rn(ls,min,max):
    ret=[]
    for i in ls:
         if len(i)<max and len(i)>min:
             print(len(i))
             ret.append(i)
    return ret

#ret,tresh = cv2.threshold(img,40,255,cv2.THRESH_BINARY)
kernel = np.ones((2,2),np.uint8)
new=cv2.Canny(img,190,1)
dilated=cv2.dilate(new, kernel)
tresh,c,hr=cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
c=rn(c, 2600, 4000)
turn_off(new)
turn_on(new,c[0])

clear_horizontal(new,image)
clear_vertical(new,image)

cv2.imwrite('result_image_end.png',image)

cv2.imshow('wnd',image)
cv2.waitKey(100)
  

Я пробовал разные подходы, но этот, похоже, работает лучше, чем другие. Я верю, что в opencv существует функция, которая может заменить это clear_horizontally и вертикально, но я не могу вспомнить ее название. Надеюсь, это поможет! введите описание изображения здесь

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