简体   繁体   English

在OpenCV中修正失真的裁剪图像(Python)

[英]Crop image with corrected distortion in OpenCV (Python)

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) . 但不幸的是, roi总是取值(0,0,0,0)

Could anyone help me? 谁能帮助我?

Thanks in advance. 提前致谢。

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. 您只需要找到图像中显示的x1y1x2y2 This can be done as follows: 这可以按如下方式完成:

import cv2
# Reads the image in grayscale
img = cv2.imread('Undistorted.jpg', 0)
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). 我所做的是中间行中的像素颜色列表,然后循环它们直到颜色高于阈值(0是黑色,255是白色)。 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. 注意:由于边界线,我从位置2开始循环,原始图像不需要。

Hope this helped! 希望这有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM