Reputation: 65
im doing this in my project for recognizing a flag shown in the camera using opencv python. i've already tried using surf, but since some of the flags has less features, like having red and blue colors as the feature of the flag, it does not always give the correct recognition. Any suggestion on what i can do to do this project of recognizing a flag based on their color histogram? you're help will be very much appreciated.
for example, i showed the flag of vietnam, the program will comparethe showed flag against database of flag images and recognize that it is the flag of vietnam.
NOTE:This is the same question in these link https://stackoverflow.com/questions/22424745/compare-a-single-image-to-database-of-images-and-find-the-closest-match-using-th which is posted by me, but i cant edit it because of slow connection
import cv2
import numpy as np
import pyttsx
import sys
import os
import operator
hbins = 180
sbins = 255
hrange = [0,180]
srange = [0,256]
ranges = hrange+srange
flags=["Cambodia.jpg","Laos.jpg","Malaysia.jpg","Myanmar.jpg","Philippines.jpg","Singapore.jpg","Thailand.jpg","Vietnam.jpg","Indonesia.jpg","Brunei.jpg"]
list_of_pics=[]
valueCompare=[]
cam = cv2.VideoCapture(0)
while True:
_, frame = cam.read(0)
cv2.imshow('asdas',frame)
list_of_pics=[]
valueCompare=[]
k=cv2.waitKey(10)
if(k==32):
cv2.imwrite("pic.jpg",frame)#the image from the camera
img = "pic.jpg"
for i in flags:
base = cv2.imread(img)
test1 = cv2.imread(i)#the flags to be compared with
rows,cols = base.shape[:2]
basehsv = cv2.cvtColor(base,cv2.COLOR_BGR2HSV)
test1hsv = cv2.cvtColor(test1,cv2.COLOR_BGR2HSV)
histbase = cv2.calcHist(basehsv,[0,1],None,[180,256],ranges)
cv2.normalize(histbase,histbase,0,255,cv2.NORM_MINMAX)
histtest1 = cv2.calcHist(test1hsv,[0,1],None,[180,256],ranges)
cv2.normalize(histtest1,histtest1,0,255,cv2.NORM_MINMAX)
comHist=cv2.compareHist(histbase,histtest1,3)
valueCompare.append(comHist)
picDict={"comhist":comHist,"name":i}
list_of_pics.append(picDict)
newlist = sorted(list_of_pics, key=operator.itemgetter('comhist')) #get the max value of all the compared images
#print newlist
matched_image=newlist[0]['name']
print matched_image
elif k == 27:
break
cv2.destroyAllWindows()
For template matching code.
k=cv2.waitKey(10)
methods = 'cv2.TM_CCOEFF_NORMED'#only the one method to be used
list_of_pics=[]
if(k==32):
for flag in flags:
img = cv2.imread('Singapore.jpg',0)
#img = img.copy()
template = cv2.imread(flag,0)
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
method = eval(methods)#
#print method
# Apply template Match
res = cv2.matchTemplate(img,template,method)
#print res
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
#print min_val, max_val
matchVal=res[0][0]
picDict={"matchVal":matchVal,"name":flag}
list_of_pics.append(picDict)
#print res[0][0]
newlist = sorted(list_of_pics, key=operator.itemgetter('matchVal'),reverse=True)
print newlist
matched_image=newlist[0]['name']
print matched_image
elif k == 27:
break
cv2.destroyAllWindows()
Upvotes: 1
Views: 7450
Reputation: 5649
After calculating the histogram, you can use the histogram matching function.
double result = compareHist( image, template, compare_method );
The value of your result will depend upon the compare_method
you use. For example, if you use correlation
as your compare method then the value of result
will lie between 0-1 and higher the value higher is the matching.
Alternative:
If you think that that size and orientation of the flag in the database and the current image are almost similar then, you dont even need to calculate the histogram. In that case, you can directly use the matchTemplate() of openCV.
Upvotes: 2