Search code examples
pythonimageimage-processingpython-imaging-librarycrop

Image Processing Cut an area that is different from a pattern


enter image description here

enter image description here

Hi,

I want to get difference between the first image and the second,

I want to cut the numbers from the image.

I am getting the difference between the pixels but the result is:

enter image description here

But what I want is:

enter image description here

Is it possible cut the image like this?

Here is what I did:

import cv2 
import numpy as np
from PIL import Image
import pytesseract
import os
import sys

img = Image.open("recherche.png").convert("RGBA")
pattern = Image.open("pattern.png").convert("RGBA")

pixels = img.load()
pixelsPattern = pattern.load()

new = Image.open("new.png").convert("RGBA")
pixelNew = new.load()

for i in range(img.size[0]):
    for j in range(img.size[1]):
         if(pixels[i,j] != pixelsPattern[i,j]):
             pixelNew[i,j] = pixels[i,j]

I am directly getting the bit difference, but It is not giving me what I want, I tried medianBlur and similar things to do it like 4th image but I am not able to make it sharp like in the 4th image.
(I created 4th image manually with paint.)


Solution

  • It's a challenging problem, because the pattern was deliberately designed to make it difficult to solve by software.

    I suggest the following steps:

    • Convert img and pattern to binary images (gray levels are not part of the number).
    • Compute absolute difference of img and pattern.
    • Apply closing morphological operation for closing small gaps.

    Here is the code:

    import cv2
    import numpy as np
    
    # Read image and pattern as Grayscale images (output of cv2.imread is numpty array).
    img = cv2.imread("recherche.png", cv2.IMREAD_GRAYSCALE)
    pattern = cv2.imread("pattern.png", cv2.IMREAD_GRAYSCALE)
    
    # Convert img and pattern to binary images (all values above 1 goes to 255)
    _, img = cv2.threshold(img, 1, 255, cv2.THRESH_BINARY)
    _, pattern = cv2.threshold(pattern, 1, 255, cv2.THRESH_BINARY)
    
    # Compute absolute difference of img and pattern (result is 0 where equal and 255 when not equal)
    dif = cv2.absdiff(img, pattern)
    
    # Apply closing morphological operation
    dif = cv2.morphologyEx(dif, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)));
    
    dif = 255 - dif  # Inverse polarity
    
    # Display result
    cv2.imshow('dif', dif)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Result:
    enter image description here

    As you can see, solution is not perfect, but getting a perfect result is very challenging...