https://github.com/TouwaErioH/Machine-Learning/tree/master/image%20identification/Histogram%20retrieval

// 优化为对图片求直方图时分块,或者加权,越靠近中心权重越高

在指定的图片数据库内,完成图片检索。图像数据按照文件名的次序大概100幅为1类,以颜色直方图为依据,

用最邻近方法或其他方法,随机抽取一张图片,利用模板匹配方法在图片库中找出100幅最相似的图片,计算查全率和查准率。

报告最后部分展示10幅来自不同类别的图片,计算查全率和查准率,展示最接近的5幅图片,并分析结果。

数据集为

http://www.vision.caltech.edu/Image_Datasets/Caltech101/Caltech101.html

参考文献  Histogram-Based Color Image Retrieval

检索方法:

采用图像的RGB三通道直方图与hsv直方图,利用欧几里得距离(Euclid),卡方比较(Chi-Square),Bhattacharyya distance(巴氏距离),相关性比较(Correlation),计算与模板的距离,找到最相近的图片。

影响性能的参数:

rgb的直方图bins,hsv直方图的h,s的bins,以及采用的检索模式。

利用API:

cv2. calcHist()

cv2.compareHist()

# -*- coding: utf-8 -*-
"""
Created on Thu Oct 17 16:01:42 2019 @author: erio
"""
'''
从下面10组中随机各选取一幅图片,
直接根据其颜色直方图在9908(0-9907)幅图片中按照最邻近方法找出最接近的图片(若超出100幅取最接近的100幅。若不足100幅则不足)
计算查全率查准率
并展示最接近的五福图片
0-99 butterfly 100 mark 1,第一组图片,选取19.bmp为模板
100-199 mountain 100 mark 2 125.bmp
300-399 mark3 376.bmp
700-799 luori 100 mark 4 747.bmp
800-899 花 mark5 850.bmp
899-998 tree 100 mark 6 940.bmp
1106-1205 mark 7 1177.bmp
1593-1692 mark 8 1596.bmp
8641 8740 mark 9 8655.bmp
9029 9128 mark 10 9037.bmp
''' import cv2
import numpy as np #转bmp
def jpg2bmp():
for i in range(0,9908):
nam='D:/image/'+str(i)+'.jpg'
nam1='D:/image/'+str(i)+'.bmp'
img = cv2.imread(nam, 1)
cv2.imwrite(nam1, img) #计算图片的hsv histogram h,s为Hue, Saturation的bins
def calchsv(start,end,h,s):
histoh=[]
for i in range(start,end+1):
img = cv2.imread('D:/image/'+str(i)+'.bmp')
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hist1 = cv2.calcHist([hsv], [0, 1], None, [h, s], [0, 180, 0, 256])
#cv2.normalize(hist1, hist1, 0, 1, cv2.NORM_MINMAX, -1); #归一化,后面数据处理的方便,其次是保证程序运行时收敛加快
histoh.append(hist1)
return histoh #计算图片的rgb histogram 。分三个通道RGB计算,每个通道bins为bins,而后拼接为一个histogram.
def calcRGBhisto(start,end,bins):
histor=[] #histo storage all histogram nparrays
for i in range(start,end+1):
img = cv2.imread('D:/image/'+str(i)+'.bmp')
#histc = cv2.calcHist([img],[0,1,2],None,[bins,bins,bins],[0,255,0,255,0,255])
hist2 = cv2.calcHist([img],[2],None,[bins],[0,255]) #np.array RGB三通道
hist0 = cv2.calcHist([img],[0],None,[bins],[0,255]) #np.array
hist1 = cv2.calcHist([img],[1],None,[bins],[0,255]) #np.array
histf=np.vstack((hist0,hist1,hist2)) #histf,当前图片的直方图的nparray
#cv2.normalize(histf, histf, 0, 1, cv2.NORM_MINMAX, -1);
histor.append(histf)
return histor #imggroup为记录搜索数据的array。形如[[19,0,99],[125,100,199]] 意味第一组图片范围为0-99,选取19号图片为标准搜索
#hisstart,hisend为要做检索的图片范围,如0,9907
#method为采用的检索方式。如Euclid为根据图片的直方图的欧几里得距离,越短认为越接近
def search(imggroup,gsize,hisstart,hisend,method): #method记录判定方式,如Euclid;
rgbeqpre=0 #平均查全率查准率
hsveqrecall=0
rgbeqrecall=0
hsveqpre=0
if (method=="Euclid"):
calmethod="Euclid"
elif (method=="Correlation"):
calmethod=cv2.HISTCMP_CORREL
elif (method=="ChiSquare"):
calmethod=cv2.HISTCMP_CHISQR
else:
calmethod=cv2.HISTCMP_BHATTACHARYYA
rgbdis=[] #rgbdis记录认为属于某组的图片的距离该组标准的距离;如dis[1]记录所有认为属于第二组的图片的距离该组标准150.bmp的距离
hsvdis=[]
rgbresult=[] #rgbresult记录结果,为gsize维数组。从0开始index越小越接近标准。如rgbresult[0]数组记录判定为属于1组的图片index。如rgbresult[0][0]=19,即为19.bmp
hsvresult=[]
rgbindex=[] #rgbindex[0]数组记录判定为属于1组的图片index。
hsvindex=[]
for i in range(0,gsize+1):
rgbdis.append([])
hsvdis.append([])
rgbindex.append([])
hsvindex.append([])
ghisrgb=[] #选取为标准的图片的histogram数组。1维数组。如ghisrgb[0]为19.bmp的histogram
ghishsv=[]
gstart=[] #记录每组开始图片index
gend=[]
for i in range(0,gsize): #ghisrgb,ghishsv 记录各个选取图片的histogram gstart记录图片所属组的开始index,
ghisrgb.append(historgb[imggroup[i][0]]) #如第一组0-99,查找19.bmp,gstart[0]=0,gend[0]=99,ghisrgb[0]=histo[19]
ghishsv.append(histohsv[imggroup[i][0]])
gstart.append(imggroup[i][1])
gend.append(imggroup[i][2])
for i in range(hisstart,hisend+1): #在hisstart-hisend的范围内,计算图片距离所选取的每幅图片距离,选择最近的认为属于该组;cnt记录距离各组距离
tprgbdis=[]
tphsvdis=[] #记录当前图片采用rgb和hsvhistogram,距离选取出的图片的距离
for j in range(0,gsize):
if (calmethod=="Euclid"):
tempr=historgb[i]-ghisrgb[j]
tempr=np.power(tempr,2)
tempdis=np.sum(tempr)
tprgbdis.append(tempdis)
temph=histohsv[i]-ghishsv[j]
temph=np.power(temph,2)
tempdis=np.sum(temph)
tphsvdis.append(tempdis)
else:
match = cv2.compareHist(historgb[i],ghisrgb[j], calmethod)
tprgbdis.append(match)
match = cv2.compareHist(histohsv[i],ghishsv[j], calmethod)
tphsvdis.append(match)
#np.argsort()用于给数组排序,返回值为从小到大元素index的值.
#假设一个数组a为[0,1,2,20,67,3],使用numpy.argsort(a),返回值应为[0,1,2,5,3,4]
if(method=="Correlation"): #Correlation -1-1,越大越接近
tpp=np.argsort(tprgbdis)
final=tpp[gsize-1] #img i 与final组correlation最接近1,认为属于final组
rgbdis[final].append(tprgbdis[final]) #将i.img距离final组标准的距离记录到rgbdis[final]数组,同时其index i记录到rgbindex[final]数组。
rgbindex[final].append(i) tpp=np.argsort(tphsvdis)
final=tpp[0] #img i 与final组euclid距离最短,认为属于final组
hsvdis[final].append(tphsvdis[final])
hsvindex[final].append(i)
else: #其余的三种方法越小越接近
tpp=np.argsort(tprgbdis)
final=tpp[0] #img i 与final组距离最短,认为属于final组
rgbdis[final].append(tprgbdis[final])
rgbindex[final].append(i) tpp=np.argsort(tphsvdis)
final=tpp[0]
hsvdis[final].append(tphsvdis[final])
hsvindex[final].append(i) #gstart[i],第i组起始index。如第0组0-99,gstart[0]=0,gend[0]=99;
#index[i][result[i][j]] index[i]为认为属于[i]组的图片的index数组.result[i]为认为属于i组的图片的dis升序排序后的索引序列
#例如 index[0]={0,24,5} 那么result[0][2]=5
for i in range(0,gsize):
rgbcorr=0 #corr 认为属于i组并且确实属于i组
hsvcorr=0
if(method=="Correlation"): #越大越好
#print(type(rgbdis))
nprd=np.array(rgbdis[i])
nphd=np.array(hsvdis[i])
rgbresult.append(np.argsort(-nprd)) #argsort 得到的result是dis降序排序后的索引序列,数组
hsvresult.append(np.argsort(-nphd)) #result数组中增加一个数组,如[]-->[[0,1,2]],判定属于第0组的图片index为0,1,2
else: #越小越好
rgbresult.append(np.argsort(rgbdis[i]))
hsvresult.append(np.argsort(hsvdis[i])) #print(rgbresult[i].size,hsvresult[i].size)
if rgbresult[i].size<=100: #若判定为i组的图片不足100幅
rgbsize=rgbresult[i].size
else: #若判定为i组的图片超过100幅,取最近的100幅
rgbsize=100
if hsvresult[i].size<=100: #若判定为i组的图片不足100幅
hsvsize=hsvresult[i].size
else: #若判定为i组的图片超过100幅,取最近的100幅
hsvsize=100
for j in range(0,rgbsize): #result[i][0]理论上是被search的图片自身,imgnum
if (gstart[i]<=rgbindex[i][rgbresult[i][j]])&(rgbindex[i][rgbresult[i][j]]<=gend[i]):
rgbcorr=rgbcorr+1
for j in range(0,hsvsize): #result[i][0]理论上是被search的图片自身,imgnum
if (gstart[i]<=hsvindex[i][hsvresult[i][j]])&(hsvindex[i][hsvresult[i][j]]<=gend[i]):
hsvcorr=hsvcorr+1
rgbclose=[]
hsvclose=[] #取最接近的5幅图片展示
for k in range(0,6):
rgbclose.append(rgbindex[i][rgbresult[i][k]])
hsvclose.append(hsvindex[i][hsvresult[i][k]])
rgbpre=rgbcorr/(rgbsize)
rgbeqpre=rgbeqpre+rgbpre
rgbrecall=rgbcorr/100
rgbeqrecall=rgbeqrecall+rgbrecall
hsvpre=hsvcorr/(hsvsize)
hsveqpre=hsveqpre+hsvpre
hsvrecall=hsvcorr/100
hsveqrecall=hsveqrecall+hsvrecall
print("imgnumber %d\n"%(imggroup[i][0]))
print("using rgb histogram %s method 's precision:%.5f ,recall:%.5f\n"%(method,rgbpre,rgbrecall))
print("using hsv histogram %s method 's precision:%.5f ,recall:%.5f\n"%(method,hsvpre,hsvrecall))
print("rgb close 5\n")
print(rgbclose)
print("hsv close 5\n")
print(hsvclose)
print("rgbeqpre: %.5f,rgbeqrecall: %.5f,hsveqpre: %.5f,hsveqrecall: %.5f\n"%(rgbeqpre/gsize,rgbeqrecall/gsize,hsveqpre/gsize,hsveqrecall/gsize)) if __name__ == '__main__':
#jpg2bmp()
histostart = 0
histoend = 9907
histobins=32
h= 90#180
s= 256 #256
historgb = calcRGBhisto(histostart,histoend,histobins)
histohsv = calchsv(histostart,histoend,h,s)
print(type(histohsv))
#每组中选取一幅图片,查找最近的100张,计算查全率查准率。如第一组0-99,查19.bmp
group=[[19,0,99],[125,100,199],[376,300,399],[747,700,799],[850,800,899],[940,899,998],
[1177,1106,1205],[1596,1593,1692],[8655,8641,8740],[9037,9029,9128]]
#group=[[50,0,99],[137,100,199],[350,300,399]]
groupsize = 10
#search(group,groupsize,histostart,histoend,"Euclid")
#search(group,groupsize,histostart,histoend,"Correlation")
#search(group,groupsize,histostart,histoend,"ChiSquare")
search(group,groupsize,histostart,histoend,"Bhattach")

根据直方图 histogram 进行简单的图像检索的更多相关文章

  1. (转)颜色直方图, HSV直方图, histogram bins

    原文链接:https://www.xuebuyuan.com/3256564.html 一个histogram,通常可以用一个列向量表示(例子中的a,b),列向量里面的每一个值就是一个bin(a,b) ...

  2. opencv python:图像直方图 histogram

    直接用matplotlib画出直方图 def plot_demo(image): plt.hist(image.ravel(), 256, [0, 256]) # image.ravel()将图像展开 ...

  3. 【POJ2136】Vertical Histogram(简单模拟)

    比较简单,按照样例模拟就好!~ #include <iostream> #include <cstdlib> #include <cstdio> #include ...

  4. 【计算机视觉】Histogram of Oriented Gridients(HOG) 方向梯度直方图

    Histogram of Oriented Gridients(HOG) 方向梯度直方图 Histogram of Oriented Gridients,缩写为HOG,是目前计算机视觉.模式识别领域很 ...

  5. 数字图像处理作业使用OpenCV - 自定义直方图

    第二次作业需要打印出来灰度直方图,当然不能使用ocv的自带calcHist函数来得到Mat对象了……结果上网搜索怎么用自己的数据创建直方图,搜到的都是直接用函数的_(:з」∠)_ 结果这个地方拖了好久 ...

  6. OpenCV-Python教程(10、直方图均衡化)

    相比C++而言,Python适合做原型.本系列的文章介绍如何在Python中用OpenCV图形库,以及与C++调用相应OpenCV函数的不同之处.这篇文章介绍在Python中使用OpenCV和NumP ...

  7. matplotlib简单示例

    一.简介 以下引用自百度百科 Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形 . 通过 Matplotlib,开发者可以仅需要 ...

  8. OpenCV-Python 直方图-3:二维直方图 | 二十八

    目标 在本章中,我们将学习查找和绘制2D直方图.这将在以后的章节中有所帮助. 介绍 在第一篇文章中,我们计算并绘制了一维直方图. 之所以称为一维,是因为我们仅考虑一个特征,即像素的灰度强度值. 但是在 ...

  9. OpenCV计算机视觉学习(9)——图像直方图 & 直方图均衡化

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...

随机推荐

  1. vue路由切换和用location切换url的区别

    最近的业务涉及到了axios的拦截器,要在request.js里面要根据状态码来跳转页面,这时候我就面对了几种跳转选择: 1.使用location.href='/url'来跳转,简单方便,但是刷新了页 ...

  2. Linux下pcstat安装踩坑教程

    首先安装golang 1.进入官方链接下载对应自己系统版本的Golang安装包:https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz root@ub ...

  3. 在QML 中用javascritpt 将中文转换拼音,可以在音标

    项目需要, 今天整理了一下.在QML调用javascrit将中文汉字转换成拼音. 感觉执行效率低.下面是主要代码. 具体代码请参考QMLPinyin 代码 ```import "./piny ...

  4. (转载)微软数据挖掘算法:Microsoft顺序分析和聚类分析算法(8)

    前言 本篇文章继续我们的微软挖掘系列算法总结,前几篇文章已经将相关的主要算法做了详细的介绍,我为了展示方便,特地的整理了一个目录提纲篇:大数据时代:深入浅出微软数据挖掘算法总结连载,有兴趣的童鞋可以点 ...

  5. 【PostgreSQL】PostgreSQL数据库浅析

    前言 工作中数据库用的不多,大部分都是简单查询一下了事,某项目中突然要求后端进行比较全面的数据库操作,现对自己学到的东西做一下总结. 简介 废话不多说,上官网地址: PostgreSQL 9.4.4 ...

  6. spark SQL (五)数据源 Data Source----json hive jdbc等数据的的读取与加载

    1,JSON数据集 Spark SQL可以自动推断JSON数据集的模式,并将其作为一个Dataset[Row].这个转换可以SparkSession.read.json()在一个Dataset[Str ...

  7. linux系统磁盘管理(磁盘阵列)

    1.磁盘阵列简介 RAID(Redundant Array of Independent Disks)即独立硬盘冗余阵列,简称磁盘阵列.磁盘阵列是由很多价格较便宜的磁盘,以硬件(RAID卡)或软件(M ...

  8. Flink-v1.12官方网站翻译-P008-Streaming Analytics

    流式分析 事件时间和水印 介绍 Flink明确支持三种不同的时间概念. 事件时间:事件发生的时间,由产生(或存储)该事件的设备记录的时间 摄取时间:Flink在摄取事件时记录的时间戳. 处理时间:您的 ...

  9. 2019牛客暑期多校训练营(第九场)D-Knapsack Cryptosystem(思维+子集和)

    >传送门<题意:给你一个有n个元素的数组,一个sum,让你找到数组的子集使得子集元素和等于sum,保证只有一个解决方案. (其中1≤n≤36,0≤ sum<9*1018,0<a ...

  10. CSAPP_BombLab实验报告

    Lab_2实验报告 目录 Lab_2实验报告 屏幕截图 考察内容 各题答案 bomb1 bomb2 bomb3 bomb4 bomb5 bomb6 secret_phase 解题思路 bomb1 bo ...