python 以圖搜圖

Como0413發表於2019-02-18
import os
import cv2 as cv
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#讀取檔案
def read_img():
    imgs = []
    # walk會返回3個引數,分別是路徑,目錄list,檔案list
    for path, lists, frame in os.walk(檔名):
        for f in frame:
            #讀取中文路徑影像
            img = cv.imdecode(np.fromfile(path + "/" + f, dtype=np.uint8), 1)
            imgs.append(img)
    return frame,imgs
#把影像分為五部分
def fif_img(img):
    img= cv.cvtColor(img, cv.COLOR_BGR2HSV)
    h,w = img.shape[:2]
    cv.line(img,(int(w/2),0),(int(w/2),h),(255,0,0),2)
    cv.line(img,(0,int(h/2)),(w,int(h/2)),(255,0,0),2)
    clie = np.zeros((h,w),np.uint8)
    cv.ellipse(clie,(int(w/2),int(h/2)),(int(0.375*w),int(0.375*h)),0,0,360,255,-1)
    img1 = cv.bitwise_and(img,img,mask=clie)

    retra,clie1 = cv.threshold(clie,0,255,cv.THRESH_BINARY_INV)
    clie2 = clie1.copy()
    clie3 = clie1.copy()
    clie4 = clie1.copy()
    cv.rectangle(clie1,(int(w/2),0),(w,h),0,-1)
    cv.rectangle(clie1,(0,int(h/2)),(w,h),0,-1)
    img2 = cv.bitwise_and(img,img,mask=clie1)

    cv.rectangle(clie2,(0,0),(int(w/2),h),0,-1)
    cv.rectangle(clie2,(int(w/2),int(h/2)),(w,h),0,-1)
    img3 = cv.bitwise_and(img,img,mask=clie2)

    cv.rectangle(clie3,(0,0),(w,int(h/2)),0,-1)
    cv.rectangle(clie3,(int(w/2),int(h/2)),(w,h),0,-1)
    img4 = cv.bitwise_and(img,img,mask=clie3)

    cv.rectangle(clie4,(0,0),(w,int(h/2)),0,-1)
    cv.rectangle(clie4,(0,int(h/2)),(int(w/2),h),0,-1)
    img5 = cv.bitwise_and(img,img,mask=clie4)
    imgs = []
    imgs.extend([img1,img2,img3,img4,img5])
    return imgs

def zft_img(name,img_score):
    colum = dict()
    for i in range(len(img_score)):
        hist = []
        imgs = fif_img(img_score[i])
        for ig in range(len(imgs)):
            hist_img = cv.calcHist([imgs[ig]], [0,1,2], None,(8,12,3), [0,180,0,256,0,256])
            #歸一化
            hist.append(pd.Series(cv.normalize(hist_img,hist_img).flatten()))
        colum[name[i]] = pd.concat(hist)
    colum = pd.DataFrame(colum)
    return colum

#一張影像的直方圖
def first_zft(name,image):
    colum = dict()
    hist = []
    imgs = fif_img(image)
    for ig in range(len(imgs)):
        hist_img = cv.calcHist([imgs[ig]], [0, 1, 2], None, (8, 12, 3), [0, 180, 0, 256, 0, 256])
        # 歸一化
        hist.append(pd.Series(cv.normalize(hist_img, hist_img).flatten()))
    colum[name] = pd.concat(hist)
    colum = pd.DataFrame(colum)
    return colum


#儲存
def Storage_img(colum):
    colum.to_csv('temp/img.csv',index=False)

#歐式距離
def o_distance(new_data,old_data):
    name = old_data.columns
    distances = dict()
    for i in range(len(name)):
        distance = 0
        for j in range(len(new_data.values)):
            distance = distance + ((new_data.values[j] - old_data[name[i]].values[j]) ** 2)
        distances[name[i]] = np.sqrt(distance)
    dist = sorted(distances.items(), key=lambda s: s[1])
    print(dist)
    name_img = []
    for i in range(10):
        print(dist[i])
        name_img.append(dist[i][0])
    return name_img

#卡方距離
def ka_distance(new_data,old_data):
    name = old_data.columns
    distances = dict()
    for i in range(len(name)):
        distance = 0
        for j in range(len(new_data.values)):
            distance = float(distance) + float(((new_data.values[j] - old_data[name[i]].values[j]) ** 2)/(new_data.values[j] + old_data[name[i]].values[j] + 0.0000001))
        distances[name[i]] = distance * 0.5
    dist = sorted(distances.items(), key=lambda s: s[1])
    name_img = []
    for i in range(10):
        name_img.append(dist[i][0])
    return name_img


#儲存影像放入新資料夾
def write_img(img):
    print("類似影像:",img)
    imgs = dict()
    for path, lists, frame in os.walk(檔名):
        for f in frame:
            # 讀取中文路徑影像
            image = cv.imdecode(np.fromfile(path + "/" + f, dtype=np.uint8), 1)
            imgs[f] = image
    for ig in img:
        cv.imwrite(儲存路徑+ig,imgs[ig])

# name,image = read_img()
# # zft_img(name,image)
# # Storage_img(zft_img(name,image))
#-*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
import pandas as pd
from yitusoutu import *

img_name = input('請輸入影像路徑名稱:')
# file = open(img_name,'r')
#讀入中文
img = cv.imdecode(np.fromfile(img_name, dtype=np.uint8), 1)
cv.imshow('img',img)
name,img_score = read_img()
old_colum = zft_img(name,img_score)
new_colum = first_zft(img_name,img)
write_img(o_distance(new_colum,old_colum))
cv.waitKey(0)
cv.destroyAllWindows()

相關文章