1. 程式人生 > >關於“用Python和OpenCV建立一個圖片搜尋引擎的完整指南”在win7作業系統python3.6環境下的測試探索

關於“用Python和OpenCV建立一個圖片搜尋引擎的完整指南”在win7作業系統python3.6環境下的測試探索

關於“用Python和OpenCV建立一個圖片搜尋引擎的完整指南”在win7作業系統python3.6下的測試探索
原部落格文章連結:http://blog.csdn.net/kezunhai/article/details/46417041




---------------
在python3.6中,上面程式需要進行修改:“(axesX, axesY) =(int(w*0.75)/2, int(h*0.75)/2)”需要更改為:“(axesX, axesY) =(int((w*0.75)/2), int((h*0.75)/2))”,否則會 提示錯誤,提示“cv2.ellipse(ellipMask,(cx,cy),(axesX,axesY),0,0,360,255,-1) ”at most 5個引數,結果是8個,因為ellipse只接受整形引數。
另外:
上面的程式還有打字錯誤:
cornerMask = np.zeros(image.shpae[:2],dtype="unit8") 
應該為:
cornerMask = np.zeros(image.shape[:2],dtype="unit8") 


好像還有一處打字錯誤,我忘記了,喜歡調程式的自己找出來。


好像是shpae應該為shape,自己查詢一下。


-----------------------
注意:
python3.6環境下的opencv3


opencv2和3之間的小坑:hist = cv2.normalize(hist).flatten()改為hist = cv2.normalize(hist,hist).flatten()


-----------
進入python安裝目錄,找到pip目錄,cmd下,進入該目錄,輸入 pip list ,即可看到opencv的版本。
我的版本是:opencv-python<3.3.1>


-------------------------------------------


win7 python3.6執行以下命令


python Search.py -i d:/picture/origin -q d:/picture/q/1.jpg -r d:/picture/test


執行後,出現PermissionError:[Errno 13] Permission denied: 'd:/picture/origin'


程式無法執行,不知道是什麼原理,給了CMD等管理員許可權也不行!
2018年1月14日


-------------------
win7 python3.6環境下(2018年1月16日):
reader = csv.reader() 
好像在修改為:
reader = csv.reader(f)


------------------




對於2018-01-14 17:19回覆的帖子進行修正:
win7 python3.6執行以下命令


python Search.py -i d:/picture/origin -q d:/picture/q/1.jpg -r d:/picture/test


執行後,出現PermissionError:[Errno 13] Permission denied: 'd:/picture/origin'


---------------

出現以上錯誤的原因已經找到,屬於引數錯誤導致的!!

具體原因是,因為要寫引數到檔案,結果我指定的路徑是資料夾,而不是具體到檔名稱,現已經更改為“d:/picture/origin/1.csv”,“1.csv”是檔名,這樣就可以運行了。

具體執行過程,應該為:
(1)在cmd命令列 視窗輸入以下命令和引數:
python index.py  -d d:/picture/origin -i d:/picture/origin/1.csv
-d  指出等待索引的圖片資料夾路徑
-i  指出索引的圖片指紋特徵的存放路徑和檔名稱。


(2)執行第1步後,再執行本步;再在cmd命令列 視窗輸入以下命令和引數:
python Search.py  -i d:/picture/origin/1.csv -q d:/picture/q/1.jpg -r d:/picture/test


截止2018年1月16日,還有錯誤,好像圖片指紋寫入到1.csv檔案的內容有誤,錯誤為:
ValueError:could not convert string to float: "0.0norigin\\2.jpg'


後續再來檢視是什麼原因導致的!!!


備註:我d:/picture/origin目錄下的圖片是以   1.jpg   2.jpg  -----  6.jpg來命名的,放了6張不同的圖片來測試程式的。

------------------------------------


2018年1月16日上午9:17分


win7 python3.6環境下,需要把index.py中的


imageID = imagePath[imagePath.rfind("/")+1:]  
修改為:
imageID = imagePath[imagePath.rfind("\\")+1:]


------------
find() 是從字串左邊開始查詢子字串匹配到的第一個索引所在位置

rfind()是從字串右邊開始查詢字串匹配到的第一個索引所在位置
例如:
>>> str='this is'
>>> str
'this is'
>>> substr='is'
>>> substr
'is'
>>> str.find(substr)
2
>>> str.rfind(substr)
5
>>> 
------------




2018年1月16日上午9:32分


win7 python3.6環境下,需要把index.py中的




output.write("%s,%sn" %(imageID,",".join(features)))
修改為:
output.write("%s,%s\n" %(imageID,",".join(features)))

注意:只是在  n"   前添加了   \




要不然生成的1.csv裡面檔名帶有路徑,而且每幅圖片之後不會回車換行。
-----------------------


2018年1月16日上午:10:30

執行出錯
OpenCV Error:Assertion failed  cpp:339:error:<-215>
如果執行出現上面錯誤,是因此給定的目錄不對。


實際應該為:
python Search.py  -i d:/picture/origin/1.csv -q d:/picture/q/1.jpg -r d:/picture/origin


說明:“d:/picture/origin”為等待檢索的的圖片放置的資料夾。“d:/picture/q/1.jpg”為等待被查詢的圖片。“-r d:/picture/origin”是顯示查詢結果,從這個資料夾


下按檢索順序提取出相似的圖片。




最終,除錯成功,一定要注意cmd下執行命令的順序,具體為:


(1)


python index.py  -d d:/picture/origin -i d:/picture/origin/1.csv




(2)


python Search.py  -i d:/picture/origin/1.csv -q d:/picture/q/1.jpg -r d:/picture/origin


備註:目錄下不能有中文的檔名稱,否則會出錯,等待以後解決!!!

python2.x 到 python3.x有很多坑,加上linux作業系統到win7作業系統有一些坑,再有就是目錄、資料夾、檔名,又有很多坑!這些坑要全部填滿才行!!!

---------------------------------------------------------------------------

---------------------------------------------------------------------------

下面是各個檔案的原始碼:

ColorDescriptor.py

"CBIR(Content-Base Image Retrieval)"
import numpy as np
import cv2

class ColorDescriptor:
    def __init__(self, bins):
        # store the number of bins for the HSV histogram
        self.bins = bins

    def describe(self, image):
        # convert the image into HSV color space
        image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        features =[]
        # grab the dimensions and compute the center of the image
        (h,w) = image.shape[:2]
        (cx,cy) = (int(w*0.5), int(h*0.5))

        # segment the image
        segments =[(0,cx,0,cy),(cx,w,0,cy),(cx,w,cy,h),(0,cx,cy,h)]

        # construct an elliptical mask representing the center of the image
        (axesX, axesY) =(int((w*0.75)/2), int((h*0.75)/2))
        ellipMask = np.zeros(image.shape[:2],np.uint8)#dtype="uint8"
        cv2.ellipse(ellipMask,(cx,cy),(axesX,axesY),0.0,0.0,360.0,255.0,-1)

        # loop over the segments
        for(startX,endX, startY, endY) in segments:
            cornerMask = np.zeros(image.shape[:2],np.uint8)#dtype="uint8"
            cv2.rectangle(cornerMask,(startX,startY),(endX,endY),255,-1)
            cornerMask = cv2.subtract(cornerMask, ellipMask)

            # compute the histogram
            hist = self.histogram(image, cornerMask)
            features.extend(hist)

        # compute the ellipse histogram
        hist = self.histogram(image, ellipMask)
        features.extend(hist)

        # return the feature vectr
        return features

    # define the function of histogram
    def histogram(self, image, mask):
        # extract the color histogram from the masked region
        hist = cv2.calcHist([image],[0,1,2],mask, self.bins,[0,180,0,256,0,256])
        hist = cv2.normalize(hist,hist).flatten()
        return hist     
        



-------------------------------------------------------------

index.py

"CBIR(Content-Base Image Retrieval)--Extract Features and Indexing"
import ColorDescriptor
import argparse
import glob
import cv2

ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True, help="Path to the directory that cntains the images to be indexed")
ap.add_argument("-i", "--index", required=True, help="Path to where the computed index will be stored")
args = vars(ap.parse_args())
cd = ColorDescriptor.ColorDescriptor((8,12,3))

#Open the output index file for writing
output = open(args["index"],"w")

# use glob to grab the image paths and loop over them
for imagePath in glob.glob(args["dataset"]+"/*.jpg"):
    # extract the image ID from the image
    imageID = imagePath[imagePath.rfind("\\")+1:]
    image = cv2.imread(imagePath)

    # describe the image
    features = cd.describe(image)

    # write feature to file
    features = [str(f) for f in features]
    output.write("%s,%s\n" %(imageID,",".join(features)))
# close index file
output.close()


-------------------------------------

Searcher.py

"CBIR(Content-Base Image Retrieval)--Similarity and Search"
import numpy as np
# use for processing index.csv
import csv

class Searcher:
    def __init__(self, indexPath):
        self.indexPath = indexPath

    def chi2_distance(self, histA, histB, eps=1e-10):
        # compute the chi-squred distance
         d = 0.5*np.sum([((a-b)**2)/(a+b+eps) for(a,b) in zip(histA,histB)])
         return d

    def search(self, queryFeatures, limit=10):
        results = {}

        # open the index file for reading
        with open(self.indexPath) as f:
            # initialize the CSV reader
            reader = csv.reader(f)

            # loop over the rows in the index
            for row in reader:
                # parse out the imageID and features,
                # then compute the chi-squared distance
                features = [float(x) for x in row[1:]]
                d = self.chi2_distance(features, queryFeatures)
                results[row[0]] = d
            f.close()
            results = sorted([(v,k) for (k,v) in results.items()])
            return results[:limit]

        #def chi2_distance(self, histA, histB, eps=1e-10):
            ## compute the chi-squred distance
            #d = 0.5*np.sum([((a-b)**2)/(a+b+eps) for(a,b) in zip(histA,histB)])
            #return d   
        
        
--------------------------------------
Search.py
"CBIR(Content-Base Image Retrieval)--Search"
import argparse

import cv2

import ColorDescriptor
import Searcher

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--index", required=True, help="Path to where the computed index will be stored")

ap.add_argument("-q", "--query", required=True, help="Path to query image")
ap.add_argument("-r", "--result_path", required = True, help="Path to the result Path")
args = vars(ap.parse_args())
cd = ColorDescriptor.ColorDescriptor((8,12,3))

# load the query image and describe it
query = cv2.imread(args["query"])
features = cd.describe(query)

# perform the search
searcher = Searcher.Searcher(args["index"])
results = searcher.search(features)


# display the query
cv2.imshow("Query", query)


# loop over the results
for(score, resultID) in results:
    # load the result image and display it
    print(args["index"]+"/"+resultID)    
    result = cv2.imread(args["result_path"]+"/"+resultID)  
    cv2.imshow("Result",result)
    cv2.waitKey(0)