计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图

目录

    • 数据集描述
    • 颜色布局描述符
      • 思路分析
      • 代码解释
      • 完整代码
      • 运行结果
    • HOG
      • 代码解释
      • 完整代码

数据集描述

数据集是Corel-1K,数据集中有一千张图片,每一百张图片为一个类别,比如海滩、汽车等等,0.jpg-99.jpg为一个类别,100.jpg-199.jpg为一个类别,以此类推。
计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第1张图片

颜色布局描述符

思路分析

参考教程:https://blog.csdn.net/qq_38204686/article/details/107187215
https://blog.csdn.net/majianxiong_lzu/article/details/90203927


先讲一下CLD的处理流程:

  • 图像分割
    将图片分割成8*8共64个小块,每个小块长宽为height/8,width/8
  • 选择每小块中的代表色
    mpeg-7标准推荐使用区域块的平均像素颜色值作为代表颜色。
  • 颜色空间转换
    需要将RGB颜色空间转换成YCbCr空间。
  • DCT转换
    对转化成YCbCr的图片进行离散余弦转换得到三组DCT矩阵。
  • 对矩阵进行之字型扫描
    计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第2张图片
    扫描的目的是对矩阵的低频系数进行分组。
  • CLD特征匹配
    通过对两个图片的CLD之间的距离计算来完成匹配。
  • 距离排序
    算法得出的距离较小的几张图,就是算法认为和样本是同类的图,但事实上得出的前几张图并不是真正的和样本同一类,据此来得到precision和recall所需的参数。
  • precision和recall
    在这里插入图片描述
    precision = (算法检索到的真实正例)/算法认为是真实正例的所有样本(包括是真的和不是真的算法认为真的)
    recall = (算法检索到的真实正例)/所有真实正例(样本里面是真的)

代码解释

  • 图像分割,将图像分割成8*8的小块,以样本小块
  #图像分割8*8
    n=8;

    (height,width,channel)=img.shape
    #print(height,width,channel) 

    block_h = np.fix(height/n); #每块的高度
    block_w=np.fix(width/n); #每块的宽度
    #print(block_h,block_w) #32.0 48.0

    im_n=np.zeros((n,n,channel))

    for i in range(n):
        for j in range(n):
            for k in range(channel):
            #确定块的坐标表达
                a = block_h * i+1;
                b = block_h * (i+1); #height: b-a
                c = block_w * j+1;
                d = block_w * (j+1); #width: d-c
            #循环到右下角的块时
                if i == (n-1):
                    b = height-1;
                if j == (n-1):
                    d = width-1;
  • 小块代表色的选择,计算小块中的平均像素颜色作为代表色。
#每块代表色的选择,实现“mpeg-7标准推荐使用区域块的平均像素颜色值作为代表颜色”
                #print(img[int(a)][int(d)][int(k)])

                arr=[img[int(a)][int(c)][k],img[int(a)][int(d)][k],img[int(b)][int(c)][k],img[int(b)][int(d)][k]]
                
                pix = np.mean(np.mean(arr));
                #print(pix)
                im_n[i][j][k]=pix
                #print(im_n)
  • 将RGB颜色空间转化成YCbCr颜色空间
 # 将rgb转换色彩空间为YCbCr
    mat = np.array(
       [[ 65.481, 128.553, 24.966 ],
        [-37.797, -74.203, 112.0  ],
        [  112.0, -93.786, -18.214]])
    offset = np.array([16, 128, 128])


    im_YCbCr = rgb2ycbcr(mat,offset,im_n)
  • DCT变换
#DCT变换
    im_DCT = np.zeros((n,n,channel)); 
    #因为dct操作只能对二维矩阵进行操作,所以这里要把y,cb,cr分别拎出来处理
    im_DCT[:,:,0] = dct(im_YCbCr[:,:,0])
    im_DCT[:,:,1] = dct(im_YCbCr[:,:,1])
    im_DCT[:,:,2] = dct(im_YCbCr[:,:,2])
    #print(im_DCT)
  • 按照之字形对矩阵进行扫描
#按照之字形扫描im_DCT存储到descript中
    zig = [[0   ,  1  ,   5  ,   6  ,  14  ,  15  ,  27  ,  28],
           [2   ,  4  ,   7  ,  13  ,  16 ,   26  ,  29  ,  42],
           [3   ,  8  ,  12 ,   17  ,  25 ,   30  ,  41  ,  43],
           [9   , 11  ,  18  ,  24  ,  31 ,   40  ,  44  ,  53],
           [10   , 19  ,  23 ,   32  ,  39 ,   45  ,  52  ,  54],
           [20   , 22  ,  33  ,  38  ,  46 ,   51  ,  55  ,  60],
           [21   , 34  ,  37  ,  47  ,  50 ,   56  ,  59  ,  61],
           [35   , 36  ,  48  ,  49  ,  57 ,   58  ,  62  ,  63 ]]
    descript = np.zeros((n*n,channel));
    for i in range (n):
        for j in range (n):
            descript[zig[i][j],:] = im_DCT[i,j,:];
            #print(descript);

    result = descript;

result就是这一张图片输出的CLD矩阵

  • 样本以0.jpg为例,依次打开1-999.jpg,命名为img2,先对每一个img2改变大小,改成和样本一样或者样本和img2都改成同样的大小(如果不改的话因为大小不同可能导致无法计算距离)。然后计算样本的CLD矩阵和img2的CLD矩阵。并根据CLD矩阵计算距离(这里用的欧式距离)。同时根据文件名编号来判断是哪个类class,比如166.jpg就是第二类,366.jpg就是第四类,总共十个类。接着用class判断是否和样本同一个类,是为1,否为0,写入new_class中。
#img2 = cv2.imread('./Corel-1K/image.orig/3.jpg')
    img_index = 0; #设置样本img的编号
    img=cv2.imread('./Corel-1K/image.orig/'+str(img_index)+'.jpg') #这里就是读取0.jpg
    img = cv2.resize(img,(200,200))
    #print('shape',img.shape)
    img_class = int((img_index)/100)+1 #算出样本img的类别,0-99为类1,100-199为类2,,以此类推
    print("class",img_class)
    
    CLD_img1 = CLD(img) #对img进行CLD处理
    cld_index=[] 
    cld_img=[]
    cld_class = []
    cld_new_class = [] 
    for i in range(0,1000):
        if i == img_index: #如果读到样本img的编号就跳过
            print("skip>>>>>>>"+str(i))
            continue;
        img2 = cv2.imread('.\\Corel-1K\\image.orig\\%d.jpg' %(i))
        img2 = cv2.resize(img2,(200,200))
        #print(img2.shape)
        #print(i)
        img2_class = int((i)/100)+1
        #print(img2_class)
        if img_class == img2_class: #判断循环取出的图片是否和样本为同一个类别
            new_class = 1
        else:
            new_class = 0
        CLD_img2 = CLD(img2);
        distances = distance_CLD(CLD_img1,CLD_img2);
        cld_index.append(i)
        cld_img.append(distances)
        cld_class.append(img2_class)
        cld_new_class.append(new_class)
  • 将CLD数据、距离、class、new_class写入dataframe中,按照距离进行升序排列。
#print(cld_img)
    test_dict = {'index':cld_index,'distance':cld_img,'original class':cld_class,'new class':cld_new_class} #把除了0.jpg之外的图片的编号、距离、类别(每一百个为一个类,
    #如0-99为一类),是否为同一类(是为1,否为0)
    df = pd.DataFrame(test_dict)
    #display(df)
    df.sort_values(by="distance",axis=0,ascending=True,inplace=True) #按照distance进行升序排列,排序后distance小的就是系统以为是和样本同类的
    #display(df)
    #print(df["index"])

原dataframe
计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第3张图片
排序后
计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第4张图片

  • 循环统计前99个里是真的同一类的图片有多少(根据new_class=1判断),据此得出每循环一次(相当于每读入一张图片)的recall和precision,并把这两个数据写入recall[ ]和precision[ ]两个数组中。
 flag = 0 #定义在new class中遇到的1的个数
    j = 0 #循环到第几个
    precision = []
    recall = []
    
    
    for c in df['new class']:
        if j== 99:
            break
        if c == 1:
            flag+=1 #当new class为1时flag+1;统计循环j次时的flag
            #print("flag",flag)
        j+=1
        pre = flag/j #precision = 真的预测为真/(真的预测为真+假的预测为真)
        rec = flag/99 #recall = 真的预测为真/(真的预测为真+真的预测为假)
        precision.append(pre) #把获得的pre加入到数组precision中
        recall.append(rec)
        
  • 画线,以recall数组为横坐标,precision为纵坐标画线。
#print("precision",precision)
    #print("recall",recall)
    drawline(recall,precision)

完整代码

#!/usr/bin/env python
# coding: utf-8

# In[1]:


import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.fftpack import dct


# In[2]:



def cvshow(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


# In[3]:


def CLD(img):
    #图像分割8*8
    n=8;

    (height,width,channel)=img.shape
    #print(height,width,channel) #256,383,3

    block_h = np.fix(height/n); #每块的高度
    block_w=np.fix(width/n); #每块的宽度
    #print(block_h,block_w) #32.0 48.0

    im_n=np.zeros((n,n,channel))

    for i in range(n):
        for j in range(n):
            for k in range(channel):
            #确定块
                a = block_h * i+1;
                b = block_h * (i+1); #height: b-a
                c = block_w * j+1;
                d = block_w * (j+1); #width: d-c
            #循环到右下角的块时
                if i == (n-1):
                    b = height-1;
                if j == (n-1):
                    d = width-1;
            #每块代表色的选择,实现“mpeg-7标准推荐使用区域块的平均像素颜色值作为代表颜色”
                #print(img[int(a)][int(d)][int(k)])

                arr=[img[int(a)][int(c)][k],img[int(a)][int(d)][k],img[int(b)][int(c)][k],img[int(b)][int(d)][k]]
                
                pix = np.mean(np.mean(arr));
                #print(pix)
                im_n[i][j][k]=pix
                #print(im_n)

    # 将rgb转换色彩空间为YCbCr
    mat = np.array(
       [[ 65.481, 128.553, 24.966 ],
        [-37.797, -74.203, 112.0  ],
        [  112.0, -93.786, -18.214]])
    offset = np.array([16, 128, 128])


    im_YCbCr = rgb2ycbcr(mat,offset,im_n)
    
    #DCT变换
    im_DCT = np.zeros((n,n,channel)); 
    #因为dct操作只能对二维矩阵进行操作,所以这里要把r,g,b分别拎出来处理
    im_DCT[:,:,0] = dct(im_YCbCr[:,:,0])
    im_DCT[:,:,1] = dct(im_YCbCr[:,:,1])
    im_DCT[:,:,2] = dct(im_YCbCr[:,:,2])
    #print(im_DCT)

    #按照之字形扫描im_DCT存储到descript中
    zig = [[0   ,  1  ,   5  ,   6  ,  14  ,  15  ,  27  ,  28],
           [2   ,  4  ,   7  ,  13  ,  16 ,   26  ,  29  ,  42],
           [3   ,  8  ,  12 ,   17  ,  25 ,   30  ,  41  ,  43],
           [9   , 11  ,  18  ,  24  ,  31 ,   40  ,  44  ,  53],
           [10   , 19  ,  23 ,   32  ,  39 ,   45  ,  52  ,  54],
           [20   , 22  ,  33  ,  38  ,  46 ,   51  ,  55  ,  60],
           [21   , 34  ,  37  ,  47  ,  50 ,   56  ,  59  ,  61],
           [35   , 36  ,  48  ,  49  ,  57 ,   58  ,  62  ,  63 ]]
    descript = np.zeros((n*n,channel));
    for i in range (n):
        for j in range (n):
            descript[zig[i][j],:] = im_DCT[i,j,:];
            #print(descript);

    result = descript;
    return result;


# In[4]:


#颜色空间转换的函数
def rgb2ycbcr(mat,offset,rgb_img):
    n=8
    channel=3
    ycbcr_img = np.zeros((n,n,channel))
    for x in range(n):
        for y in range(n):
            ycbcr_img[x, y, :] = np.round(np.dot(mat, rgb_img[x, y, :] * 1.0 / 255) + offset)
    return ycbcr_img


# In[5]:


def distance_CLD(img1,img2):
    return np.sqrt(np.sum(np.square(img1 - img2))) #欧式距离


# In[6]:


def drawline(recall,precision):
    plt.plot(recall,precision)
    plt.xlabel("recall")
    plt.ylabel("precision")
    plt.title('PR Graph of CLD')
    plt.show()


# In[7]:


if __name__ == "__main__":
    #img2 = cv2.imread('./Corel-1K/image.orig/3.jpg')
    img_index = 0; #设置样本img的编号
    img=cv2.imread('./Corel-1K/image.orig/'+str(img_index)+'.jpg') #这里就是读取0.jpg
    img_class = int((img_index)/100)+1 #算出样本img的类别,0-99为类1,100-199为类2,,以此类推
    print("class",img_class)
    
    CLD_img1 = CLD(img) #对img进行CLD处理
    cld_index=[] 
    cld_img=[]
    cld_class = []
    cld_new_class = [] 
    for i in range(0,1000):
        if i == img_index: #如果读到样本img的编号就跳过
            print("skip>>>>>>>"+str(i))
            continue;
        img2 = cv2.imread('.\\Corel-1K\\image.orig\\%d.jpg' %(i))
        img2 = cv2.resize(img2,(256,383))
        #print(img2.shape)
        #print(i)
        img2_class = int((i)/100)+1
        #print(img2_class)
        if img_class == img2_class: #判断循环取出的图片是否和样本为同一个类别
            new_class = 1
        else:
            new_class = 0
        CLD_img2 = CLD(img2);
        distances = distance_CLD(CLD_img1,CLD_img2);
        cld_index.append(i)
        cld_img.append(distances)
        cld_class.append(img2_class)
        cld_new_class.append(new_class)
        
    #print(cld_img)
    test_dict = {'index':cld_index,'distance':cld_img,'original class':cld_class,'new class':cld_new_class} #把除了0.jpg之外的图片的编号、距离、类别(每一百个为一个类,
    #如0-99为一类),是否为同一类(是为1,否为0)
    df = pd.DataFrame(test_dict)
    #display(df)
    df.sort_values(by="distance",axis=0,ascending=True,inplace=True) #按照distance进行升序排列,排序后distance小的就是系统以为是和样本同类的
    #display(df)
    #print(df["index"])
    
    flag = 0 #定义在new class中遇到的1的个数
    j = 0 #循环到第几个
    precision = []
    recall = []
    
    
    for c in df['new class']:
        if j== 99:
            break
        if c == 1:
            flag+=1 #当new class为1时flag+1;统计循环j次时的flag
            #print("flag",flag)
        j+=1
        pre = flag/j #precision = 真的预测为真/(真的预测为真+假的预测为真)
        rec = flag/99 #recall = 真的预测为真/(真的预测为真+真的预测为假)
        precision.append(pre) #把获得的pre加入到数组precision中
        recall.append(rec)
        
    #print("precision",precision)
    #print("recall",recall)
    drawline(recall,precision)


# In[ ]:




运行结果

计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第5张图片

HOG

参考教程:https://blog.csdn.net/abc13526222160/article/details/102574369?utm_medium=distribute.pc_relevant.none-task-blog-title-6&spm=1001.2101.3001.4242
先来讲讲HOG的过程:

  • 图像预处理
    对图像的尺寸进行调整,用伽马校正调整曝光使图像更接近于人眼的状态。

  • 计算梯度
    计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第6张图片
    水平梯度为10,垂直梯度为32。
    梯度幅度为
    在这里插入图片描述
    梯度方向为
    计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第7张图片
    梯度方向为0-180度。

  • 计算梯度直方图
    计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第8张图片
    计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第9张图片

  • block归一化
    降低光照的影响

  • 得到HOG特征向量

代码解释

用的是skimage.feature.hog的方法来得到HOG特征向量

def HOG(img):
    img_gray = rgb2gray(img)/255.0 #转化成灰度图像并进行归一化
    fd = hog(img_gray, orientations=10, pixels_per_cell=[8,8], cells_per_block=[8,8], visualize=False, 
             transform_sqrt=True,block_norm='L2-Hys')
    #print(fd)
    return fd

其他步骤和CLD差不多

完整代码

#!/usr/bin/env python
# coding: utf-8

# In[1]:


import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from skimage.feature import hog


# In[2]:


def rgb2gray(im): #灰度化
    gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140
    return gray


# In[3]:


def HOG(img):
    img_gray = rgb2gray(img)/255.0 #转化成灰度图像并进行归一化
    fd = hog(img_gray, orientations=10, pixels_per_cell=[8,8], cells_per_block=[8,8], visualize=False, 
             transform_sqrt=True,block_norm='L2-Hys')
    #print(fd)
    return fd
    


# In[4]:


def distance_HOG(img1,img2):
    return np.sqrt(np.sum(np.square(img1 - img2))) #欧式距离


# In[5]:


def drawline(recall,precision):
    plt.plot(recall,precision)
    plt.xlabel("recall")
    plt.ylabel("precision")
    plt.title('PR Graph of CLD')
    plt.show()


# In[7]:


if __name__ == "__main__":
    #img2 = cv2.imread('./Corel-1K/image.orig/3.jpg')
    img_index = 0; #设置样本img的编号
    img=cv2.imread('./Corel-1K/image.orig/'+str(img_index)+'.jpg') #这里就是读取0.jpg
    img = cv2.resize(img,(200,200))
    img_class = int((img_index)/100)+1 #算出样本img的类别,0-99为类1,100-199为类2,,以此类推
    print("class",img_class)
    print('img',img.shape)
    
    HOG_img1 = HOG(img) #对img进行HOG处理
    print("HOG_img1 size",HOG_img1.shape)
    hog_index=[] 
    hog_img=[]
    hog_class = []
    hog_new_class = [] 
    
    for i in range(0,1000):
        if i == img_index: #如果读到样本img的编号就跳过
            print("skip>>>>>>>"+str(i))
            continue;
        img2 = cv2.imread('.\\Corel-1K\\image.orig\\%d.jpg' %(i))
        img2 = cv2.resize(img2,(200,200))
        #print(img2.shape)
        #print(i)
        img2_class = int((i)/100)+1
        #print(img2_class)
        if img_class == img2_class: #判断循环取出的图片是否和样本为同一个类别
            new_class = 1
        else:
            new_class = 0
        HOG_img2 = HOG(img2);
        distances = distance_HOG(HOG_img1,HOG_img2);
        hog_index.append(i)
        hog_img.append(distances)
        hog_class.append(img2_class)
        hog_new_class.append(new_class)
        
    #print(cld_img)
    test_dict = {'index':hog_index,'distance':hog_img,'original class':hog_class,'new class':hog_new_class} #把除了0.jpg之外的图片的编号、距离、类别(每一百个为一个类,
    #如0-99为一类),是否为同一类(是为1,否为0)
    df = pd.DataFrame(test_dict)
    #display(df)
    df.sort_values(by="distance",axis=0,ascending=True,inplace=True) #按照distance进行升序排列,排序后distance小的就是系统以为是和样本同类的
    #display(df)
    #print(df["index"])
    
    flag = 0 #定义在new class中遇到的1的个数
    j = 0 #循环到第几个
    precision = []
    recall = []
    
    
    for c in df['new class']:
        if j== 99:
            break
        if c == 1:
            flag+=1 #当new class为1时flag+1;统计循环j次时的flag
            #print("flag",flag)
        j+=1
        pre = flag/j #precision = 真的预测为真/(真的预测为真+假的预测为真)
        rec = flag/99 #recall = 真的预测为真/(真的预测为真+真的预测为假)
        precision.append(pre) #把获得的pre加入到数组precision中
        recall.append(rec)
        
    #print("precision",precision)
    #print("recall",recall)
    drawline(recall,precision)


计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第10张图片


阳老师真的好耐心哦,一步一步指导我,尽管我问很傻的问题都会回答,太感人了555.

计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第11张图片


昨天晚上和弟弟还有室友吃小火锅,太舒服了,然后喝了rio(乳酸菌的还不错),uno局老放垃圾话,导致自己老输,脸上贴的条条可以绕地球一圈,气鼠(虽然但是放垃圾话真的好爽)。然后玩的忘记时间了,忘记背单词(马上组队打卡就要结束了来这出,以后每天都定好闹钟背单词!),也忘记买鞋555555555555555,下次记住了大促前不能组局玩耍555.


11.25更新
贴一下老师的代码

#!/usr/bin/env python
# coding: utf-8

# # 1.图像检索实验

# In[1]:


import cv2  #opencv 读取进来为BGR格式
import matplotlib.pyplot as plt
import numpy as np
import os

#一个魔法指令,不需要采用plt.show()显示图像
get_ipython().run_line_magic('matplotlib', 'inline')


# In[2]:


def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


# In[3]:


# 把目标图放在64x128的灰色图片中间,方便计算描述子
def get_hog_descriptor(image):
    hog = cv2.HOGDescriptor()
    h, w = image.shape[:2]
    rate = 64 / w
    image = cv2.resize(image, (64, np.int(rate*h)))
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    bg = np.zeros((128, 64), dtype=np.uint8)
    bg[:,:] = 127
    h, w = gray.shape
    dy = (128 - h) // 2
    bg[dy:h+dy,:] = gray
    descriptors = hog.compute(bg, winStride=(8, 8), padding=(0, 0))
    return descriptors


# In[4]:


# 计算图像的color layout descriptor(CLD)
rows = 8
cols = 8
def  get_CLD_descriptor(img):
        averages = np.zeros((rows,cols,3))
        imgH, imgW, _ = img.shape
        for row in range(rows):
            for col in range(cols):
                slice = img[int(imgH/rows * row): int(imgH/rows * (row+1)), int(imgW/cols*col) : int(imgW/cols*(col+1))]
                average_color_per_row = np.mean(slice, axis=0)
                average_color = np.mean(average_color_per_row, axis=0)
                average_color = np.uint8(average_color)
                averages[row][col][0] = average_color[0]
                averages[row][col][1] = average_color[1]
                averages[row][col][2] = average_color[2]
        icon = cv2.cvtColor(np.array(averages, dtype=np.uint8), cv2.COLOR_BGR2YCR_CB)
        y, cr, cb = cv2.split(icon)
        dct_y = cv2.dct(np.float32(y))
        dct_cb = cv2.dct(np.float32(cb))
        dct_cr = cv2.dct(np.float32(cr))
        dct_y_zigzag = []
        dct_cb_zigzag = []
        dct_cr_zigzag = []
        flip = True
        flipped_dct_y = np.fliplr(dct_y)
        flipped_dct_cb = np.fliplr(dct_cb)
        flipped_dct_cr = np.fliplr(dct_cr)
        for i in range(rows + cols -1):
            k_diag = rows - 1 - i
            diag_y = np.diag(flipped_dct_y, k=k_diag)
            diag_cb = np.diag(flipped_dct_cb, k=k_diag)
            diag_cr = np.diag(flipped_dct_cr, k=k_diag)
            if flip:
                diag_y = diag_y[::-1]
                diag_cb = diag_cb[::-1]
                diag_cr = diag_cr[::-1]
            dct_y_zigzag.append(diag_y)
            dct_cb_zigzag.append(diag_cb)
            dct_cr_zigzag.append(diag_cr)
            flip = not flip
        return np.concatenate([np.concatenate(dct_y_zigzag), np.concatenate(dct_cb_zigzag), np.concatenate(dct_cr_zigzag)])


# In[5]:


# 测试图像
img_color = cv2.imread('images/lena.jpg')

hog_des = get_hog_descriptor(img_color)
print(hog_des.shape)

CLD_des = get_CLD_descriptor(img_color)
print(CLD_des.shape)
#print(CLD_des)


# In[6]:


allpath=[]
allname=[]

#获取文件列表
def get_allfile(path):
    allfilelist=os.listdir(path)
    # 遍历该文件夹下的所有目录或者文件
    for file in allfilelist:
        filepath=os.path.join(path,file)
        # 如果是文件夹,递归调用函数
        if os.path.isdir(filepath):
            getallfile(filepath)
        # 如果不是文件夹,保存文件路径及文件名
        elif os.path.isfile(filepath):
            allpath.append(filepath)
            allname.append(file)
            
    return allpath, allname


# In[7]:


def get_file(root_path,all_files=[]):
   
    # 递归函数,遍历该文档目录和子目录下的所有文件,获取其path
    files = os.listdir(root_path)
    for file in files:
        if not os.path.isdir(root_path + '/' + file):   # not a dir
            all_files.append(root_path + '/' + file)
        else:  # is a dir
            get_file((root_path+'/'+file),all_files)
    return all_files


# In[8]:


img_path = "data/Corel-1K"
#allpath, allname = get_allfile(img_path) #获取文件目录 + 文件名

#print(allpath[0])
#print(allname[0])

allpath = get_file(img_path)

# list_name = allpath[0].split('/');
print(len(allpath))
print(allpath[0])


# 遍历所有文件
hogs = []
labels = []
for file in allpath:   
    print(allpath.index(file)+1)
    img = cv2.imread(file)
    hog_feat = get_hog_descriptor(img)
    
    list_name = file.split('/')
    class_label = list_name[2]
    
    hogs.append(hog_feat)
    labels.append(class_label)   
    
allpath.clear()   #情况列表


# In[9]:


dist = np.zeros((1000,1000))
for i in np.arange(1000):
                hog1 = hogs[i]
                #print(i)
                for j in np.arange(1000):
                    hog2 = hogs[j]
                    dist[i][j] = np.sqrt(np.sum(np.square(hog1 - hog2 )))
                    #dist[i][j]= np.linalg.norm(hog1 - hog2)
                    #np.delete(hog1)
                    #np.delete(hog2)


# In[10]:


print(dist[0][0])
#print(dist[0])
index = dist.argsort()   #按照二维数组从小到大进行排序,返回数组的索引

index_count = np.zeros((1000,999))
for i in range(1000):
    for j in range(1,1000):
        if labels[index[i][0]] == labels[index[i][j]]:
            index_count[i][j-1] = 1
        else:
            index_count[i][j-1] = 0
                
# 画出检索结果的Precision与Recall曲线
#Precision = np.zeros((1000,10))
#Recall = np.zeros((1000,10))
#for i in range(1000):
#    for j in range(1,11):
#        Precision[i][j-1]= np.sum(index_count[i][:j*10])/(j*10)
#        Recall[i][j-1] = np.sum(index_count[i][:j*10])/100

#P = Precision.mean(axis = 0)  #二维数组按照列求平均值
#R = Recall.mean(axis =0)

#plt.figure(1)
#plt.plot(P, R)
#plt.xlim([0,1])
#plt.ylim([0,1])
#plt.show()
#print(np.max(np.where(index_count[0]==1)))


# In[11]:


# 画出检索结果的Precision与Recall曲线

Precision = np.zeros((1000,99))
Recall = np.zeros((1000,99))
for i in range(1000):
    list_num = np.where(index_count[0]==1)
    for j in range(99):
        Precision[i][j]= np.sum(index_count[i][:list_num[0][j]])/list_num[0][j]
        Recall[i][j]= np.sum(index_count[i][:list_num[0][j]])/99
        
P = Precision.mean(axis = 0)  #二维数组按照列求平均值 
R = Recall.mean(axis =0)

plt.figure(1)
plt.plot(R, P)
plt.xlabel('Recall')
plt.ylabel('Precision')
#plt.xlim([0,1])
#plt.ylim([0,1])
plt.show()


# ### 基于Color Layout Descriptor(CLD)特征的图像检索

# In[12]:


img_path = 'data/Corel-1K'

allpath = get_file(img_path)

# 遍历所有文件
CLDs = []
labels = []
for file in allpath:   
    print(allpath.index(file)+1)
    img = cv2.imread(file)
    CLD_feat = get_CLD_descriptor(img)
    
    list_name = file.split('/')
    class_label = list_name[2]
    
    CLDs.append(CLD_feat)
    labels.append(class_label)   
    
allpath.clear()   #情况列表


# In[13]:


dist2 = np.zeros((1000,1000))
for i in np.arange(1000):
                CLD1 = CLDs[i]
                for j in np.arange(1000):
                    CLD2 = CLDs[j]
                    dist2[i][j] = np.sqrt(np.sum(np.square(CLD1 - CLD2 )))


# In[14]:


index = dist2.argsort()   #按照二维数组从小到大进行排序,返回数组的索引

index_count = np.zeros((1000,999))
for i in range(1000):
    for j in range(1,1000):
        if labels[index[i][0]] == labels[index[i][j]]:
            index_count[i][j-1] = 1
        else:
            index_count[i][j-1] = 0


# In[15]:


# 画出检索结果的Precision与Recall曲线
Precision = np.zeros((1000,99))
Recall = np.zeros((1000,99))
for i in range(1000):
    list_num = np.where(index_count[0]==1)
    for j in range(99):
        Precision[i][j]= np.sum(index_count[i][:list_num[0][j]])/list_num[0][j]
        Recall[i][j]= np.sum(index_count[i][:list_num[0][j]])/99
        
P = Precision.mean(axis = 0)  #二维数组按照列求平均值 
R = Recall.mean(axis =0)

plt.figure(1)
plt.plot(R, P)
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.show()


计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第12张图片
计算机视觉 实验四 分别使用颜色布局描述符(Color Layout Descriptor)与方向梯度直方图(HOG)实现图像检索,并且画出图像的PR曲线图_第13张图片

你可能感兴趣的:(计算机视觉,计算机视觉)