使用OpenCV(Python)修正失真并裁剪图像

5
我已经在其他帖子中寻找答案并尝试了几种方法,但都没有解决我的问题。我正在尝试纠正图像中的光学畸变并且成功了,但现在我想裁剪图像以删除结果图像中的弯曲黑色边框。因此,总之,这是我的问题:

problem

我想这样裁剪:

enter image description here

我已经尝试了以下代码进行裁剪:

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]

但是不幸的是,roi 总是取值为 (0,0,0,0)

有人可以帮我吗?

提前感谢。


谢谢您的回复。当alpha=0时,只得到了左侧中间部分的一个小区域。它不能正常工作。 - Carlos
你能把修复失真的代码也发一下吗?这正是我在寻找的...既能裁剪又能修复失真... - Jonathan Corrin
1个回答

7

由于空白部分在图像中心具有最大/最小值,您可以查找中间线并查看颜色何时发生变化。下面的图像可能会澄清这一点:

enter image description here

你只需要在图片中找到显示的 x1y1x2y2 即可。可以按照以下步骤完成:
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)

我所做的是列出中间行的像素颜色列表,然后循环它们直到颜色超过阈值(0为黑色,255为白色)。当检测到第一个改变颜色的像素时,位置被存储并且循环中断。输出是裁剪后的图像:

enter image description here

注意:我从位置2开始循环,因为有边框线,在原始图像中不需要这样做。
希望这能帮到你!

2
太棒了,我的朋友。完美的解答并且讲解得非常清楚明白。恭喜你,非常感谢! - Carlos
2
非常感谢!我刚刚意识到void部分不一定对称,所以您还需要循环反转的列表。已经编辑好了! - ebeneditos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接