Search code examples
pythonnumpyopencvimage-processingobject-detection

Finding corners of box and crop Image


Hey Guys I am working with numpy and opencv and want to get a image cropped by the contours of it. Here is one example what picture i want to crop by the edges, enter image description here

And i want that the yellow line (rectangle) get cropped by python,

enter image description here

import numpy as np
import cv2
from PIL import Image


image = cv2.imread('4.png')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([103, 131, 70])
upper = np.array([179, 234, 255])
mask = cv2.inRange(image, lower, upper)
result = cv2.bitwise_and(result, result, mask=mask)


print(image.shape)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey()

Solution

  • You can opt for the LAB color space.

    Now why use LAB color space over HSV?

    • It's easier to segment the color of your choice by analyzing the chroma channels.
    • There is no need to manually fix a range (unlike in HSV color space). Otsu threshold will help.

    What is LAB color space?

    • L-channel : represents brightness value in the image
    • A-channel : represents variation of color between red and green
    • B-channel : represents variation of color between blue and yellow

    Visit this page for better visualization

    After analyzing the a-channel and b-channel for the LAB converted image, we will make use of the a-channel since the box can be segmented easily here.

    img = cv2.imread('image_path')
    lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    a_component = lab[:,:,1]
    

    enter image description here

    th = cv2.threshold(a_component,127,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
    contours, hierarchy = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    c = max(contours, key = cv2.contourArea)
    
    black = np.zeros((img.shape[0], img.shape[1]), np.uint8)
    mask = cv2.drawContours(black,[c],0,255, -1)
    

    enter image description here

    result = cv2.bitwise_and(result, result, mask=mask)
    

    enter image description here

    Hope this is the result you were expecting