Search code examples
pythonimageopencvimage-processingcrop

Crop image opencv python


Please help me crop this image. I need to split the image below into two images to compare them, but I want to cut them in such a way that the two cropped images have the same size and remove the excess area between the two images. Orignal picture

I have used the following code to crop, but it seems to be not very effective.

import cv2
import numpy as np

# Đọc bức ảnh gốc
image = cv2.imread('2.jpg')

# Lấy chiều cao và chiều rộng của ảnh
height, width = image.shape[:2]

# Tính vị trí cắt giữa hai ảnh
middle = width // 2

# Cắt và lấy hai phần bức ảnh
image1 = image[:, :middle]
image2 = image[:, middle:]

# Tìm contours trong ảnh 1
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
_, thresh1 = cv2.threshold(gray1, 1, 255, cv2.THRESH_BINARY)
contours1, _ = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
x1, _, w1, _ = cv2.boundingRect(contours1[0])

# Tìm contours trong ảnh 2
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
_, thresh2 = cv2.threshold(gray2, 1, 255, cv2.THRESH_BINARY)
contours2, _ = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
x2, _, w2, _ = cv2.boundingRect(contours2[0])

# Cắt bỏ vùng đen giữa hai ảnh
image1 = image1[:, x1:(x1+w1)]
image2 = image2[:, x2:(x2+w2)]

# Hiển thị hai ảnh đã cắt
cv2.imshow('Image 1', image1)
cv2.imshow('Image 2', image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Please help me with the code to crop the image as requested.


Solution

  • Here is an alternate approach using Python/OpenCV.

    • Read the input
    • Threshold on black
    • Apply morphology open to remove thin regions
    • Get the counts of non-zero pixels along each column
    • Find the first (min) location where the counts are greater than some threshold (99%)
    • Find the last (max) location where the counts are greater than some threshold (99%)
    • Use those values to crop the image into the two parts
    • Save the results

    Input:

    enter image description here

    import cv2
    import numpy as np
    
    # read the image
    img = cv2.imread('tom_and_jerry.jpg')
    hh, ww = img.shape[:2]
    
    # threshold on black
    lower = (0,0,0)
    upper = (10,10,10)
    thresh = cv2.inRange(img, lower, upper)
    
    # apply morphology open to remove thin lines
    kernel = np.ones((3,3), np.uint8)
    morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    
    # count the number of non-zero pixels in each column
    counts = np.count_nonzero(morph, axis=0)
    
    # get the first and last position where counts >= 99% of hh
    T=0.99
    min = np.amin(np.where(counts>=T*hh))
    max = np.amax(np.where(counts>=T*hh))
    print(min,max)
    
    # crop start x and width w
    x = min-1
    w = max-min+2
    
    
    # crop the image into two parts
    crop1 = img[0:hh, 0:x]
    crop2 = img[0:hh, x+w:ww]
    
    # save results
    cv2.imwrite('tom_and_jerry_thresh.jpg', thresh)
    cv2.imwrite('tom_and_jerry_morph.jpg', morph)
    cv2.imwrite('tom_and_jerry_crop1.jpg', crop1)
    cv2.imwrite('tom_and_jerry_crop2.jpg', crop2)
    
    # show results
    cv2.imshow('thresh', thresh)
    cv2.imshow('morph', morph)
    cv2.imshow('crop1', crop1)
    cv2.imshow('crop2', crop2)
    cv2.waitKey(0)
    

    Crop 1:

    enter image description here

    Crop 2:

    enter image description here