我正在使用距离与角度签名进行图像表示。计算对象引用签名时没有问题。但是当我将它与旋转或缩放的相同对象进行比较时,它永远不会产生相同或甚至类似的签名。我确定距离测量或签名规范化存在一些错误,但我找不到它。
以下是我的图片:
cartridge.png
cartridge.png http://image.prntscr.com/image/e65e63583ea04194925335ce04062395.png
盒rotate.png
cartridge-rotate.png http://image.prntscr.com/image/f95215df0f3c4fd999ef1286f3a69ba3.png
盒scale.png
cartridge-scale.png http://image.prntscr.com/image/9217c9ea98114296ad40ef7ceacde6c0.png
签名:
cartridge.png:[100,0,2,4,9,17,22,20,19,19,21,27,25,21,17,13,11,10,11,12,16, 21,19,17,16,12,11,14,16,18,24,30,24,20,19,9]
cartridge-rotate.png:[100,5,5,82,6,6,8,11,9,8,7,5,1,0,1,1,3,5,7,7, 7,7,7,8,10,9,7,83,4,4,5,5,6,8,7,83]
cartridge-scale.png:[100,0,5,13,24,34,31,30,31,34,44,44,34,26,21,17,16,18,21,26, 34,30,26,25,18,18,19,22,27,37,46,39,33,29,16,94]
这是我的代码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
import cv2 as cv
import timeit as exe
def getCentroid(img):
# Find object centroid
row, col = img.shape
xVal = 0
yVal = 0
n = 0.0
for x in range(0,row):
for y in range(0,col):
if (img[x,y] == 255):
xVal += x
yVal += y
n += 1.0
xVal /= n
yVal /= n
return [np.int64(np.round(xVal)),np.int64(np.round(yVal))]
def getDistanceAngle(img, centroid, alpha):
# Compute distance from centroid to boundary with specified angle
row, col = img.shape
xVal = np.float64(centroid[0])
yVal = np.float64(centroid[1])
x1 = centroid[0]
y1 = centroid[1]
x2 = x1
y2 = y1
distance = 0.0
r = 0
while (((xVal >= 0 and xVal < row) and (yVal >=0 and yVal < col)) and (img[np.int64(xVal),np.int64(yVal)] == 0)):
x2 = np.int64(xVal)
y2 = np.int64(yVal)
xVal = x1 + r * (np.cos(np.deg2rad(alpha)))
yVal = y1 + r * (np.sin(np.deg2rad(alpha)))
r += 1
# Euclidean distance between (x1,y1) and (x2,y2)
distance = np.sqrt(np.power(x2 - x1, 2) + np.power(y2 - y1, 2))
return distance
def getSignature(img, centroid, delta):
# Get signature of object
alpha = 0.0
signature = []
while (alpha < 360.0):
signature.append(getDistanceAngle(img, centroid, alpha))
alpha += delta
return signature
def normalization(signature, th):
# Perform normalization to object signature
# Deal with object rotation and scaling
# Deal with object rotation
# Find maximum value in signature
# Split and merge signature
# Maximum value moved to the first place
maxIdx = np.argmax(signature)
sortSig = signature[maxIdx:]
sortSig.extend(signature[0:maxIdx])
# Deal with object scaling
# Find maximum and minimum value
# Rescale each value to the maximum range (th -> threshold)
normSig = []
maxSig = np.float64(np.max(signature))
minSig = np.float64(np.min(signature))
for s in sortSig:
distTemp = ((s - minSig) / (maxSig - minSig)) * th
distance = np.int64(np.round(distTemp))
normSig.append(distance)
return normSig
def verifySignature(sigOri, sigList, th):
# Compare original signature with other signatures
length = len(sigOri)
rateList = []
accList = []
for sig in sigList:
sim = 0.0
for i in range(0,length):
if (sigOri[i] == sig[i]):
sim += 1.0
rate = sim / length * 100.0
rateList.append(rate)
if (100.0 - rate <= th):
accList.append(True)
else:
accList.append(False)
return [rateList, accList]
def main():
# Main functon
img = []
img.append(cv.imread("C:/Users/Kadek/Documents/Python/OpenCV/test/boundary/cartridge.png",0))
img.append(cv.imread("C:/Users/Kadek/Documents/Python/OpenCV/test/boundary/cartridge-rotate.png",0))
img.append(cv.imread("C:/Users/Kadek/Documents/Python/OpenCV/test/boundary/cartridge-scale.png",0))
centroid = []
signature = []
normalized = []
for i in range(0,3):
centroid.append(getCentroid(img[i]))
signature.append(getSignature(img[i], centroid[i], 10.0))
normalized.append(normalization(signature[i], 100.0))
print(normalized[i])
img[i][centroid[i][0],centroid[i][1]] = 100
verification = verifySignature(normalized[0], [normalized[1],normalized[2]], 8.5)
print(verification[0],verification[1])
plt.imshow(img[2], cmap = cm.Greys_r)
start = exe.default_timer()
main()
end = exe.default_timer()
exeTime = end - start
print(exeTime)