## Crop image with corrected distortion in OpenCV (Python)

Question

I've been looking for a response in other posts and trying several ways to get it but I couldn't find anything solving my problem. I'm trying to correct optical distortion in an image and I get it, but now I want to crop my image in order to delete the curved black borders in the result image. So, in summary, this is my problem:

I want to crop like this:

I've tried to crop with the following code:

``````h,  w = corrected_img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(cameraMTX,distortionCoeffs,(w,h),1,(w,h))
x,y,w,h = roi
desired_result = corrected_img[y:y+h, x:x+w]
``````

But unfortunately `roi` always takes the value `(0,0,0,0)`.

Could anyone help me?

Show source

## Answers to Crop image with corrected distortion in OpenCV (Python) ( 1 )

1. As the void part has its maximum/minimum in the middle of the image, you could look for the middle lines and see when there is a change of color. The image below may clarify this:

You just need to find the `x1`, `y1`, `x2` and `y2` shown in the image. This can be done as follows:

``````import cv2
# Reads the image in grayscale
h, w = img.shape
x1, x2, y1, y2 = (0,0,0,0)

# Color threshold of the void part
void_th = 10

# List of colors in the vertical an horizontal lines that cross the image in the middle
vertical = [img[i, int(w/2)] for i in range(h)]
horizontal = [img[int(h/2), i] for i in range(w)]

# Reverses both lists
vertical_rev = vertical[::-1]
horizontal_rev = horizontal[::-1]

# Looks when the change of color is done
for i in range(2,h):
if vertical[i] > void_th and y1 == 0:
y1 = i
if vertical_rev[i] > void_th and y2 == 0:
y2 = i
if y1 != 0 and y2 != 0:
break
for i in range(2,w):
if horizontal[i] > void_th and x1 == 0:
x1 = i
if horizontal_rev[i] > void_th and x2 == 0:
x2 = i
if x1 != 0 and x2 != 0:
break

desired_result = img[y1:h-y2, x1:w-x2]
cv2.imshow('Crop', desired_result)
``````

What I did is a list of the pixel colors in the middle lines, and then loop them until the color is above a threshold (0 is Black and 255 is White). When the first pixel that changes of color is detected, the position is stored and the loop breaks. The output is the cropped image:

Note: I started looping from position 2 because of the border line, with the original image this is not needed.

Hope this helped!