OpenCV:检测覆盖标签的边界框
OpenCV : Detecting bounding-box covering the label
我有类似背景噪音的类似图像。
使用 OpenCV,有没有办法检测覆盖标签的区域的面积(检测轮廓)。
或者至少,是否可以检测到 "rough" 覆盖标签区域的边界框?
我已经尝试完成这个任务,可能不允许推广这个算法的主要问题是如何选择合适的轮廓。我有两个值(轮廓长度)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 和垂直的函数,但我不记得它的名字了。希望能帮助到你!
我有类似背景噪音的类似图像。 使用 OpenCV,有没有办法检测覆盖标签的区域的面积(检测轮廓)。 或者至少,是否可以检测到 "rough" 覆盖标签区域的边界框?
我已经尝试完成这个任务,可能不允许推广这个算法的主要问题是如何选择合适的轮廓。我有两个值(轮廓长度)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 和垂直的函数,但我不记得它的名字了。希望能帮助到你!