Image 将图像片段放回原始图像

Image 将图像片段放回原始图像,image,image-processing,Image,Image Processing,我正在寻找一种算法,将图像中的切块重新组合到原始图像中的正确位置。在上下文中,这是自动解决验证码的解决方案的一部分。例如: 我看过opencv sticher类,但这似乎只适用于创建“全景图像”,即图像的边缘应该粘在一起。该解决方案可能涉及某种形状检测,以查看工件的位置,然后检查工件是否“适合”上下文。此解决方案很简单。该算法复制了人类解决问题的方式。以下是步骤: 识别钥匙 遮住锁孔 猜猜钥匙孔应该装什么(使用修补) 将钥匙+钥匙孔与修复图像进行比较 最佳拟合将出现在修复猜测和钥匙+钥匙孔图像

我正在寻找一种算法,将图像中的切块重新组合到原始图像中的正确位置。在上下文中,这是自动解决验证码的解决方案的一部分。例如:


我看过opencv sticher类,但这似乎只适用于创建“全景图像”,即图像的边缘应该粘在一起。该解决方案可能涉及某种形状检测,以查看工件的位置,然后检查工件是否“适合”上下文。

此解决方案很简单。该算法复制了人类解决问题的方式。以下是步骤:

  • 识别钥匙
  • 遮住锁孔
  • 猜猜钥匙孔应该装什么(使用修补)
  • 将钥匙+钥匙孔与修复图像进行比较
  • 最佳拟合将出现在修复猜测和钥匙+钥匙孔图像之间的差异最小的位置。这个.gif解释了

    这是我使用的代码:

    import cv2
    import numpy as np
    
    # Read image
    img = cv2.imread('/home/stephen/Desktop/capcha.png')
    # Get key and mask of key
    key = img[567:700, 145:234]
    lower, upper = np.array([0,0,0]),np.array([101,255,255])
    hsv = cv2.cvtColor(key, cv2.COLOR_BGR2HSV)
    key_mask = cv2.inRange(hsv, lower, upper)
    key = cv2.bitwise_and(key, key, mask = key_mask)
    kernel = np.ones((20,20), np.uint8)
    # Create a dilated mask so the key will surely fill keyhole
    dilated_key_mask = key_mask.copy()
    cv2.morphologyEx(dilated_key_mask, cv2.MORPH_DILATE, kernel)
    
    # https://stackoverflow.com/questions/189943/how-can-i-quantify-difference-between-two-images
    from scipy.misc import imread
    from scipy.linalg import norm
    from scipy import sum, average
    
    def compare_images(img1, img2):
        # normalize to compensate for exposure difference, this may be unnecessary
        # consider disabling it
        img1 = normalize(img1)
        img2 = normalize(img2)
        # calculate the difference and its norms
        diff = img1 - img2  # elementwise for scipy arrays
        m_norm = sum(abs(diff))  # Manhattan norm
        z_norm = norm(diff.ravel(), 0)  # Zero norm
        return (m_norm, z_norm)
    
    def to_grayscale(arr):
        "If arr is a color image (3D array), convert it to grayscale (2D array)."
        if len(arr.shape) == 3:
            return average(arr, -1)  # average over the last axis (color channels)
        else:
            return arr
    
    def normalize(arr):
        rng = arr.max()-arr.min()
        amin = arr.min()
        return (arr-amin)*255/rng
    
    # Scan through the image
    h, w, _ = img.shape
    dh, dw, _ = key.shape
    close_diff = h*w
    
    graph = np.zeros((300,600,3), np.uint8)
    for row in range(h-dh):
        for col in range(w-dw):
            # Create a mask of the image with the key missing
            img_temp = img.copy()
            img_mask = np.zeros((h,w), np.uint8)
            img_mask[row:row+dh, col:col+dw] = dilated_key_mask
            img_temp = cv2.bitwise_and(img_temp, img_temp, mask = 255-img_mask)
            # Inpaint to guess what should be there
            inpaint = cv2.inpaint(img_temp,img_mask,3,cv2.INPAINT_TELEA)
            # Mask the key of the image 
            actual = img_temp.copy()
            actual[row:row+dh, col:col+dw] += key
    
            # Compare the images
            img1 = to_grayscale(inpaint)
            img2 = to_grayscale(actual)
            _, difference = compare_images(img1, img2)
    
            cv2.imshow('inpaint', inpaint)
            cv2.imshow('actual', actual)
            cv2.waitKey(1)
    
            if difference < close_diff:
                cv2.waitKey()
                close_diff = difference
                best_fit = row, col
    
    cv2.destroyAllWindows()
    
    导入cv2
    将numpy作为np导入
    #读取图像
    img=cv2.imread('/home/stephen/Desktop/capcha.png')
    #获取密钥和密钥的掩码
    key=img[567:700,145:234]
    下,上=np.数组([0,0,0]),np.数组([101255255])
    hsv=cv2.cvt颜色(键,cv2.COLOR\u BGR2HSV)
    按键屏蔽=cv2.inRange(hsv,下,上)
    key=cv2.按位_和(key,key,mask=key_mask)
    kernel=np.one((20,20),np.uint8)
    #创建一个放大的面具,这样钥匙肯定会填满钥匙孔
    扩展的密钥掩码=密钥掩码。复制()
    cv2.morphologyEx(放大的按键遮罩,cv2.Morpho放大,内核)
    # https://stackoverflow.com/questions/189943/how-can-i-quantify-difference-between-two-images
    从scipy.misc导入imread
    来自scipy.linalg导入规范
    从scipy导入总和,平均值
    def比较图像(img1、img2):
    #正常化以补偿曝光差异,这可能是不必要的
    考虑禁用它
    img1=正常化(img1)
    img2=正常化(img2)
    #计算差值及其范数
    对于scipy阵列,diff=img1-img2#元素
    m#u范数=和(abs(diff))#曼哈顿范数
    z_norm=norm(diff.ravel(),0)#零norm
    返回(m_范数,z_范数)
    def至_灰度(arr):
    如果arr是彩色图像(3D数组),请将其转换为灰度(2D数组)
    如果len(arr.shape)==3:
    返回平均值(arr,-1)#最后一个轴上的平均值(颜色通道)
    其他:
    返回arr
    def正常化(arr):
    rng=arr.max()-arr.min()
    阿明=到达最小值()
    返回(arr-amin)*255/rng
    #浏览图像
    h、 w,ug=img.shape
    dh,dw,=key.shape
    闭合差=h*w
    图=np.0((300600,3),np.uint8)
    对于范围内的行(h-dh):
    对于范围内的列(w-dw):
    #创建缺少密钥的图像掩码
    img_temp=img.copy()
    img_mask=np.zero((h,w),np.uint8)
    img\u mask[行:行+dh,列:列+dw]=放大的键\u mask
    img_temp=cv2.按位_和(img_temp,img_temp,mask=255-img_mask)
    #猜猜那里应该有什么
    inpaint=cv2.inpaint(img_temp,img_mask,3,cv2.inpaint_TELEA)
    #遮罩图像的关键点
    实际值=img_临时副本()
    实际[行:行+dh,列:列+dw]+=键
    #比较图像
    img1=至_灰度(修复)
    img2=至_灰度(实际)
    _,差异=比较图像(img1、img2)
    cv2.imshow(“修复”,修复)
    cv2.imshow(“实际”,实际)
    cv2.等待键(1)
    如果差异
    它提醒我刚体对接问题。