pythonopencvcontourboundarydrawrectangle

How to find and draw largest rectangle inside contour area?


i want to compare an image with specific pixel using

(score, diff) = compare_ssim(grayA[y:y+h, x:x+w], grayB[y:y+h, x:x+w], full=True)

But that function only support rectangle ROI. And my ROI is a contour. To compare that i need largest rectangle inside the contour. How to find largest rectangle inside contour area ?

Sample image enter image description here


Solution

  • According to your OP, I suggest to use warpAffine to rotate the ROI to a rectangle shape, because the ROI is already in rectangle shape but rotated. Here is a simple sample:

    import cv2
    import numpy as np
    
    img = cv2.imread("1.png")
    (H,W,c) = img.shape
    print("shape = {},{}".format(H,W))
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _,thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY_INV)
    
    _,contours,_ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    
    res = np.zeros_like(img)
    c = np.squeeze(contours[0])
    
    # find rectangle's conner points
    x = sorted(c, key=lambda a:a[0])
    left = x[0]
    right = x[-1]
    y= sorted(c, key=lambda a:a[1])
    top = y[0]
    bottom = y[-1]
    
    cv2.circle(img, (left[0],left[1]), 4, (0, 0, 255), -1)
    cv2.circle(img, (right[0],right[1]), 4, (0, 0, 255), -1)
    cv2.circle(img, (top[0],top[1]), 4, (0, 0, 255), -1)
    cv2.circle(img, (bottom[0],bottom[1]), 4, (0, 0, 255), -1)
    
    #calculate rectangle's shape
    roi_w = int(np.sqrt((top[0]-right[0])*(top[0]-right[0])+(top[1]-right[1])*(top[1]-right[1])))
    roi_h = int(np.sqrt((top[0]-left[0])*(top[0]-left[0])+(top[1]-left[1])*(top[1]-left[1])))
    
    pts1 = np.float32([top,right,left])
    
    # keep the top coords and calculate new coords for left and right
    new_top = top
    new_right = [top[0] + roi_w, top[1]]
    new_left = [top[0], top[1] + roi_h]
    pts2 = np.float32([new_top,new_right,new_left])
    
    #rotate 
    matrix = cv2.getAffineTransform(pts1, pts2)
    result = cv2.warpAffine(img, matrix, (W,H))
    cv2.drawContours(res, [contours[0]], 0, (0,255,0), 3)
    
    # extract roi
    roi = result[new_top[1]:new_left[1],new_top[0]:new_right[0]]
    
    cv2.imshow("img",img)
    cv2.imshow("result",result)
    cv2.waitKey(0)
    

    enter image description here enter image description here enter image description here