python图像去重及相似度估计
2019-03-30 本文已影响1人
涂山容容
数据不足,于是就从网上找了个爬虫的代码,爬了一些数据下来,不甚欣喜,然后就开始筛选,筛着筛着发现有的图片长的好像哦,然后就按照大小排了序,我的妈呀,一排排都是一样样的,这必须先把重复的图像都去掉啊。
查了一下,可以用md5算法来做,感觉这个思路挺巧妙的,md5本身是来做校验的,在一定程度上,可以说是唯一的,所以可以通过计算每一个图像的md5值,如果相同就认为是一样的,就移除。
import hashlib
def remove_same_piture_by_get_md5(path):
img_list = os.listdir(path)
print(img_list)
md5_list =[]
for filename in img_list:
m = hashlib.md5()
mfile = open(os.path.join(path,filename), "rb")
m.update(mfile.read())
mfile.close()
md5_value = m.hexdigest()
#print(md5_value)
if (md5_value in md5_list):
os.remove(os.path.join(path,filename))
else:
md5_list.append(md5_value)
print('total %s images'%len(md5_list))
在处理视频序列的时候,发现由于帧率很高,很多图像都是相似的,那么相似的图像重复标注,太累了,所以就想找个相似性度量的方式去除一部分。
初步想法. 简单粗暴的隔几帧抽一张,确实是又快又好。但是觉得,对一个程序猿来说,是不是要用点更好大上的算法。然后就搜了一下。
最后选了两种
1.感知哈希算法
思路很简单,就是给每一幅图提取特征(这个特征是64位的二进制数值,然后比较这些特征的不同,有多少位不同就定义成不同的文件)
具体步骤:
1.将图像resize成8*8的灰度缩略图,计算缩略图均值。
2.将缩略图的值与均值比较,大的为1,小的为0。得到定义的图像哈希值。
- 比较图像的哈希值,如果有五位不同,就认为是不同的,否则相同。
2.基于结构相似度的
其实还有基于灰度直方图的,自己觉得不太靠谱,就没用。还有基于sift的,感觉很难算,折中选了用结构相似度的,这个的话直接调用了 skimage.measure 中的 compare_ssim。又是一键解决。然后,自己思考了一下,比较相似度的话,只要和前面五张比就好了,太多的意义不大,反倒是增加了损耗。还是要增加约束。
def remove_simillar_picture_by_perception_hash(path):
img_list = os.listdir(path)
hash_dic = {}
hash_list = []
count_num = 0
for img_name in img_list:
try:
img = cv2.imread(os.path.join(path, img_name))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
count_num+=1
print(count_num)
except:
continue
img = cv2.resize(img,(8,8))
avg_np = np.mean(img)
img = np.where(img>avg_np,1,0)
hash_dic[img_name] = img
if len(hash_list)<1:
hash_list.append(img)
else:
for i in hash_list:
flag = True
dis = np.bitwise_xor(i,img)
if np.sum(dis) < 5:
flag = False
os.remove(os.path.join(path, img_name))
break
if flag:
hash_list.append(img)
def remove_simillar_image_by_ssim(path):
img_list = os.listdir(path)
img_list.sort()
hash_dic = {}
save_list = []
count_num = 0
for i in range(len(img_list)):
try:
img = cv2.imread(os.path.join(path, img_list[i]))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.resize(img,(256, 256))
count_num+=1
except:
continue
if count_num==1:
save_list.append(img_list[i])
continue
elif len(save_list) <5:
flag = True
for j in range(len(save_list)):
com_img = cv2.imread(os.path.join(path,save_list[j]))
com_img = cv2.cvtColor(com_img,cv2.COLOR_BGR2GRAY)
com_img = cv2.resize(com_img,(256,256))
sim = compare_ssim(img,com_img)
if sim > 0.4:
os.remove(os.path.join(path,img_list[i]))
flag = False
break
if flag:
save_list.append(img_list[i])
else:
for save_img in save_list[-5:]:
com_img = cv2.imread(os.path.join(path,save_img))
com_img = cv2.cvtColor(com_img, cv2.COLOR_BGR2GRAY)
com_img = cv2.resize(com_img, (256, 256))
sim = compare_ssim(img,com_img)
if sim > 0.4:
os.remove(os.path.join(path,img_list[i]))
flag = False
break
if flag:
save_list.append(img_list[i])