如何从图像中删除黑色部分?

时间:2012-05-17 09:00:18

标签: c++ image-processing opencv image-stitching

我使用OpenCV函数和C ++将两个图像拼接在一起。现在我遇到的问题是最终图像包含一个大的黑色部分。

最终图像应该是包含有效部分的矩形。 我的图片如下:

enter image description here

如何删除黑色部分?

3 个答案:

答案 0 :(得分:17)

mevatron的答案是在保留完整图像的同时将黑色区域的数量最小化的一种方法。

另一种选择是删除完整的黑色区域,在这里您也会丢失图像的某些部分,但结果将是一个整洁的矩形图像。下面是Python代码。

在这里,您可以找到图像的三个主要角落,如下所示:

enter image description here

我标记了这些值。 (1,x2), (x1,1), (x3,y3)。它基于您的图像从(1,1)开始的假设。

代码:

第一步与mevatron相同。模糊图像以消除噪点,使图像达到阈值,然后找到轮廓。

import cv2
import numpy as np

img = cv2.imread('office.jpg')
img = cv2.resize(img,(800,400))

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray,3)

ret,thresh = cv2.threshold(gray,1,255,0)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

现在找到最大的轮廓,即你的形象。这是为了避免噪音,如果有的话(很可能没有)。或者你可以使用mevatron的方法。

max_area = -1
best_cnt = None

for cnt in contours:

    area = cv2.contourArea(cnt)
    if area > max_area:
        max_area = area
        best_cnt = cnt

现在近似轮廓以去除找到的轮廓值中不必要的点,但它保留所有角点值。

approx = cv2.approxPolyDP(best_cnt,0.01*cv2.arcLength(best_cnt,True),True)

现在我们找到了角落。

首先,我们找到(x3,y3)。这是最远点。所以x3*y3会非常大。因此,我们找到所有点对的产品,并选择具有最大产品的对。

far = approx[np.product(approx,2).argmax()][0]

下一步(1,x2)。第一个元素是1,然后第二个元素是最大值。

ymax = approx[approx[:,:,0]==1].max()

下一步(x1,1)。这是第二个元素为1的点,然后第一个元素是最大值。

xmax = approx[approx[:,:,1]==1].max()

现在我们找到了minimum values in (far.x,xmax) and (far.y, ymax)

x = min(far[0],xmax)
y = min(far[1],ymax)

如果使用(1,1)和(x,y)绘制矩形,则得到如下结果:

enter image description here

所以你裁剪图像以纠正矩形区域。

img2 = img[:y,:x].copy()

结果如下:

enter image description here

See, the problem is that you lose some parts of the stitched image.

答案 1 :(得分:8)

您可以使用thresholdfindContoursboundingRect执行此操作。

所以,这是一个使用python接口执行此操作的快速脚本。

stitched = cv2.imread('stitched.jpg', 0)
(_, mask) = cv2.threshold(stitched, 1.0, 255.0, cv2.THRESH_BINARY);

# findContours destroys input
temp = mask.copy()
(contours, _) = cv2.findContours(temp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# sort contours by largest first (if there are more than one)
contours = sorted(contours, key=lambda contour:len(contour), reverse=True)
roi = cv2.boundingRect(contours[0])

# use the roi to select into the original 'stitched' image
stitched[roi[1]:roi[3], roi[0]:roi[2]]

看起来像这样: enter image description here

注意:原始图像可能不需要排序,但使用压缩图像会导致在使用低阈值时出现一些压缩失真,这就是我使用排序进行后处理的原因。

希望有所帮助!

答案 2 :(得分:0)

您可以使用活动轮廓(气球/蛇)来准确选择黑色区域。可以找到演示here。 OpenCV中提供了活动轮廓,请检查cvSnakeImage

相关问题