将切出的图像根据相似度处理成黑白图并粘回原来的地方

简述

上一篇文章已经介绍了如何求相似度,如果想了解可以点下面的链接。这次我对求相似度的算法进行了优化,并实现了切出图像的处理并还原。
上文博客: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)

整个过程大概就是这样,感兴趣的可以尝试一下,有什么问题可以交流一下,共同进步~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值