简述
上一篇文章已经介绍了如何求相似度,如果想了解可以点下面的链接。这次我对求相似度的算法进行了优化,并实现了切出图像的处理并还原。
上文博客:https://blog.csdn.net/python_qiao/article/details/100592222
相似度算法
为了提高相似度的准确性,需要先对图像的RGB三通道进行处理。
def create_rgb_hist(image):
h, w, c = image.shape
# 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
# 16*16*16的意思为三通道每通道有16个bins
rgbhist = np.zeros([16 * 16 * 16, 1], np.float32)
bsize = 256 / 16
for row in range(h):
for col in range(w):
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
# 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
index = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
# 该处形成的矩阵即为直方图矩阵
rgbhist[int(index), 0] += 1
plt.ylim([0, 10000])
plt.grid(color='r', linestyle='--', linewidth=0.5, alpha=0.3)
return rgbhist
最后返回的是hist列表,接下来依靠compareHist函数来求相似度。
#直方图比较
def hist_compare(image1, image2):
#image1 = cv2.resize(image1,(40,40))
#生成两个图像的hist列表
hist1 = create_rgb_hist(image1)
hist2 = create_rgb_hist(image2)
# 进行三种方式的直方图比较
match1 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_BHATTACHARYYA)
match2 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
#match3 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CHISQR)
print("巴氏距离:%s, 相关性:%s" %(match1, match2))
return match1,match2
根据相似度转换为黑白图
有了上面求出的两个相似度值,可以设定条件来讲图像处理成黑色或白色。
def return_image(image,match1,match2):
im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
if(match1>0.8 and match2<0.2):
(_, thresh) = cv2.threshold(im, 255, 255, cv2.THRESH_BINARY)
else:
(_, thresh) = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY)
im1 = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
return im1
这里需要注意的是,为了使用二值化的方法,必须先将图像变成灰度图,处理之后一定要再将图像转换成BGR三通道图,因为如果图像格式不一致会报错。
将处理好的图像粘回原处
def paste_image(image1,image2):
top_img = Image.fromarray(image1)
image2 =Image.fromarray(image2)
image2.paste(top_img,(x,y))
image = np.asarray(image2)
return image
这里也需要注意,fromarray函数是将数组转化为图像,asarray函数是将图像转化为数组。因为一开始使用imread读取图像信息后,图像就变成了数组格式,所以这里使用过fromarray后一定要使用asarray,保持图像格式的一致性。
主函数调用
新加的模块功能就这么多,下面需要调用这些功能来实现啦。
对了,还需要一个滑动窗口的设置
#设置滑动窗口
def sliding_window(image, stepSize, windowSize):
# slide a window across the image
for y in range(0, image.shape[0], stepSize):
for x in range(0, image.shape[1], stepSize):
# yield the current window
yield (x, y, image[y:y + windowSize[1], x:x + windowSize[0]])
主函数
if __name__ == '__main__':
src1 = cv2.imread("picture/10.jpg")
cv2.imshow("original",src1)
src2 = cv2.imread("picture/9.jpg")
src3 = cv2.resize(src2,(400,400))
# 自定义滑动窗口的大小
(winW, winH) = (40, 40)
# 步长大小
stepSize = 40
clone = src3.copy()
cnt = 0
for (x, y, window) in sliding_window(src3, stepSize=stepSize, windowSize=(winW, winH)):
if window.shape[0] != winH or window.shape[1] != winW:
continue
cv2.rectangle(clone, (x, y), (x + winW, y + winH), (0, 255, 0), 1)
cv2.imshow("Window", clone)
cv2.waitKey(1000)
slice = src3[y:y + winH, x:x + winW]
cv2.namedWindow('sliding_slice', 0)
cv2.imshow('sliding_slice', slice)
cv2.waitKey(1000)
match1,match2 = hist_compare(src1,slice)
now = return_image(slice,match1,match2)
clone = paste_image(now, clone)
cnt = cnt + 1
cv2.imwrite("13.jpg",clone)
整个过程大概就是这样,感兴趣的可以尝试一下,有什么问题可以交流一下,共同进步~