如何检测图像的那部分被移动了?

2024-06-01 10:22:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有几张文件的照片,我需要确定文件是否已更改。 所以这项任务包括两个部分:1。文本移位。检测到特殊文本已移位:

enter image description here

注意铭文:TEST TEXT HERE有一个间隙(在S字母处)。在

  1. 第二个任务:背景图像的类似偏移,如下所示: enter image description here

我的问题: 有什么方法可以检测到相同的位移吗?它们可以是水平的和垂直的。 我总是知道测试题词(在第一个任务中),我总是有高质量的装饰样品。我有一组照片需要检查。在

我的解决方法。 1第一个想法:在每张照片上叠加正确的铭文,并检查周围像素的颜色-如果有很多红色像素,就会发生偏移。所以我可以选文字,但不能选图片。 2关于图像,我想到了傅立叶变换。如果图像上有一个间隙,则在同一个坐标上存在函数跳跃。但我不知道这种方法的一些实现。在


首先,我知道这类问题太宽泛了。 How to detect a shift between images 但我已经发现了类似的,所以希望不要关闭! 第二点-我对任何算法开放-古典学习和机器学习。在


Tags: 文件方法texttest图像文本here字母
1条回答
网友
1楼 · 发布于 2024-06-01 10:22:37

我用解决问题的方法做了一个脚本。这可能不是最好的方法,但我希望这能有所帮助,或者给你一个新的观点,如何进行。在

首先,我会将图像转换为HSV颜色空间,因为转换为二进制不是最好的方法,因为tekst周围有很多噪声。转换后,可以使用cv2.inRange和一个阈值提取文本。然后我搜索轮廓并在一个新的空白蒙版上画出来。在

enter image description hereenter image description here

下一步是执行一个开放,将附近的轮廓合并成一个大轮廓。打开后是膨胀,以删除左上角剩余的字符T。在

enter image description hereenter image description here

接下来,我将再次搜索轮廓并绘制一个边界矩形。如果轮廓是一个完美的正方形,那么您将看不到该矩形,但是如果轮廓移动,它将生成内部有两个较小矩形(oposite颜色)的矩形:

enter image description here

最后用阈值大小再次搜索轮廓并在图像上绘制。在

结果:

enter image description here

代码:

# Import modules
import cv2
import numpy as np

# Read the image and transform to HSV colorspace.
img = cv2.imread('ID.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Extract the red text.
lower_red = np.array([150,150,50])
upper_red = np.array([200,255,255])
mask_red = cv2.inRange(hsv, lower_red, upper_red)

# Search for contours on the mask.
_, contours, hierarchy = cv2.findContours(mask_red,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

# Mask for processing.
mask = np.ones(img.shape, np.uint8)*255

# Iterate through contours and draw them on mask.
for cnt in contours:
    cv2.drawContours(mask, [cnt], -1, (0,0,0), -1)

# Perform opening to unify contours.
kernel = np.ones((15,15),np.uint8)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

# Perform dilation to remove some noises.
kernel_d = np.ones((2,2),np.uint8)
dilation = cv2.dilate(opening,kernel_d,iterations = 1)

# Seraching for contours on the new mask.
gray_op = cv2.cvtColor(dilation, cv2.COLOR_BGR2GRAY)
_, threshold_op = cv2.threshold(gray_op, 150, 255, cv2.THRESH_BINARY_INV)
_, contours_op, hierarchy_op = cv2.findContours(threshold_op, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

# Iterate through contours and draw a bounding rectangle.
for cnt in contours_op:
    x,y,w,h = cv2.boundingRect(cnt)
    cv2.rectangle(threshold_op,(x,y),(x+w,y+h),(255,255,255),1)

# Seraching for contours again on the new mask.
_, contours_f, hierarchy_f = cv2.findContours(threshold_op, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

# Iterate through contours and add size for thresholding out the rest.
for cnt in contours_f:
    size = cv2.contourArea(cnt)
    if size < 1000:
        x,y,w,h = cv2.boundingRect(cnt)
        cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),-1)

# Display the result.   
cv2.imshow('img', img)

对于第二幅图像,它将不起作用,因为图像的复杂性不同。在

在第二张图上,我会试着放大它,这样只剩下底部的3条线(或者在移位的情况下是4条)并计算轮廓的数量。如果存在4个轮廓,则会移动。在

enter image description here

或者第二张照片的第二张照片。使用cv2.reactangle()将等高线分割为3个独立的等高线,并计算它们到所创建直线的最小距离。这样,即使拆分发生在底线偏移之前,也可以计算。在

第二个图像的代码:

^{pr2}$

结果:

enter image description here

enter image description here

enter image description here

希望能有点帮助。干杯!在

相关问题 更多 >