#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 и вертикально, но я не могу вспомнить ее название. Надеюсь, это поможет!