python - 使用简单的 True/False 判断一个特定图像是否包含在另一个图像中

标签 python opencv

我想知道一张大图片是否包含一张小图片。小图可以是半透明的(类似于水印,所以不是完全填充的照片)。我试过关于这个主题的不同 SO 答案,但它们都与精确照片匹配,但我正在寻找的是照片是否以 80% 的准确度存在,因为照片将是原始照片的有损渲染版本.

这是我正在搜索的图像将如何生成的过程: 使用任何照片,在 Photoshop 中为其添加半透明的“水印”并保存。然后我想检查创建的照片中是否存在“水印”,并具有一定的准确度(80% 就足够了)。

我试过使用他们 docs page 上提供的原始模板匹配示例但我几乎没有得到任何匹配项。

这是我正在使用的代码:

import cv2
import numpy as np

img_rgb = cv2.imread('photo2.jpeg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('small-image.png', 0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.7
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv2.imshow('output', img_rgb)
cv2.waitKey(0)

这是我一直用于测试的照片,因为这与我尝试匹配的照片相似。

small-image.png photo2.jpeg

最佳答案

我假设整个水印将具有相同的 RGB 值,而文本将具有稍微不同的 RGB 值,否则该技术将不起作用。基于此,我们可以获得小图像像素的 RGB 值,并通过使用 cv2.inRange 将其视为掩码来查找大图像中的那些像素值。类似地,还会使用这些像素值为小图像创建掩码。

small = cv2.imread('small_find.png')
large = cv2.imread('large_find.jpg')
pixel = np.reshape(small[3,3], (1,3))
lower =[pixel[0,0]-10,pixel[0,1]-10,pixel[0,2]-10]
lower = np.array(lower, dtype = 'uint8')
upper =[pixel[0,0]+10,pixel[0,1]+10,pixel[0,2]+10]
upper = np.array(upper, dtype = 'uint8')
mask = cv2.inRange(large,lower, upper)
mask2 = cv2.inRange(small, lower, upper)

我不得不采用 20 的缓冲区值,因为这些值在大图像中没有明显匹配,否则只有 1 在上部或下部就足够了。然后我们在 mask 中找到轮廓并找到其边界矩形的值,该矩形被切出并 reshape 为 mask2 的大小。

im, contours, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(large, contours, -1, (0,0,255), 1)
cnt = max(contours, key = cv2.contourArea)
x,y,w,h = cv2.boundingRect(cnt)
wanted_part = mask[y:y+h, x:x+w]
wanted_part = cv2.resize(wanted_part, (mask2.shape[1], mask2.shape[0]), interpolation = cv2.INTER_LINEAR)

Output

两个面具并排(将它们倒置,否则它们不可见)。

为了比较它们,您可以使用任何参数并检查它是否满足您的条件。我使用均方误差,得到的误差仅为 6.20,非常低。

def MSE(img1, img2):
    squared_diff = img1 - img2
    summed = np.sum(squared_diff)
    num_pix = img1.shape[0] * img1.shape[1] #img1 and 2 should have same shape
    err = summed / num_pix
    return err

关于python - 使用简单的 True/False 判断一个特定图像是否包含在另一个图像中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54431410/

相关文章:

matlab - 基本矩阵在 matlab 中不断变化,但使用 open cv 时相同。可能是什么原因?

iOS如何屏蔽图片背景色

linux - 如何在 Ubuntu 9.10 上检查 openCV

python - 如何在同一绘图上正确绘制个别年份的月度数据

python - 了解mfcc的输出

python - 如何从javascript代码中提取字符串?

python - 将字典中列表的值转换为大写/小写

python - 将单引号替换为双引号 python pandas 数据框

visual-studio-2010 - 无法从 'cv::Mat' 转换为 'void *'

c++ - 使用opencv进行视频处理的音频输出