OpenCV-Python|OpenCV-Python 图像全景拼接stitch及黑边处理
OpenCV版本:4.5.3.56
算法实现思路:
代码实现:
- 图像拼接
- 全景轮廓提取
- 轮廓最小正矩形
- 腐蚀处理
- 裁剪
import cv2
import numpy as npdef stitch(image):
# 图像拼接
# stitcher = cv2.createStitcher(False)# OpenCV 3.X.X.X使用该方法
stitcher = cv2.Stitcher_create(cv2.Stitcher_PANORAMA)# OpenCV 4.X.X.X使用该方法,cv2.Stitcher_create()也可以
status, pano = stitcher.stitch(image)# 黑边处理
if status == cv2.Stitcher_OK:
# 全景图轮廓提取
stitched = cv2.copyMakeBorder(pano, 10, 10, 10, 10, cv2.BORDER_CONSTANT, (0, 0, 0))
gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]# 轮廓最小正矩形
mask = np.zeros(thresh.shape, dtype="uint8")
(x, y, w, h) = cv2.boundingRect(cnts[0])# 取出list中的轮廓二值图,类型为numpy.ndarray
cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)# 腐蚀处理,直到minRect的像素值都为0
minRect = mask.copy()
sub = mask.copy()
while cv2.countNonZero(sub) > 0:
minRect = cv2.erode(minRect, None)
sub = cv2.subtract(minRect, thresh)# 提取minRect轮廓并裁剪
cnts = cv2.findContours(minRect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
(x, y, w, h) = cv2.boundingRect(cnts[0])
stitched = stitched[y:y + h, x:x + w]cv2.imshow('stitched', stitched)
cv2.imwrite('stitched.jpg', stitched)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print('图像匹配的特征点不足')if __name__ == "__main__":
image1 = cv2.imread('data/space1.jpg')
image2 = cv2.imread('data/space2.jpg')
image3 = cv2.imread('data/space3.jpg')
image = image1, image2, image3
stitch(image)
原图:
文章图片
文章图片
文章图片
图像拼接
# stitcher = cv2.createStitcher(False)# OpenCV 3.X.X.X使用该方法
stitcher = cv2.Stitcher_create(cv2.Stitcher_PANORAMA)# OpenCV 4.X.X.X使用该方法,cv2.Stitcher_create()也可以
status, pano = stitcher.stitch(image)
OpenCV-Python的stitch实现了图像拼接方法。在OpenCV 3.X.X.X系列版本中,使用cv2.createStitcher。在OpenCV 4.X.X.X系列版本中,使用cv2.Stitcher_create或者cv2.Stitcher_create,两者用法一致。
stitch有两个返回值,一个是status,表示是否拼接成功;另一个是pano,当图像匹配的特征点足够时,拼接成功,返回全景图,当图像匹配的特征点不够时,拼接失败,返回None。效果如下:
文章图片
黑边处理 全景图拼接完成后,会出现图像边界外的黑色像素(0),使全景图不完美。可采取如下方法去除黑边:全景图轮廓提取、轮廓最小正矩形、腐蚀处理。
全景图轮廓提取
# 全景图轮廓提取
stitched = cv2.copyMakeBorder(pano, 10, 10, 10, 10, cv2.BORDER_CONSTANT, (0, 0, 0))
gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
文章图片
轮廓最小正矩形
# 轮廓最小正矩形
mask = np.zeros(thresh.shape, dtype="uint8")
(x, y, w, h) = cv2.boundingRect(cnts[0])# 取出list中的轮廓二值图,类型为numpy.ndarray
cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)
文章图片
腐蚀处理
# 腐蚀处理,直到minRect的像素值都为0
minRect = mask.copy()
sub = mask.copy()
while cv2.countNonZero(sub) > 0:
minRect = cv2.erode(minRect, None)
sub = cv2.subtract(minRect, thresh)
创建了两个mask副本:
通过cv2.erode()腐蚀minRect,直到sub为全黑(0)。用类似动图演示,上面为sub,下面为minRect:
- minRect,最小mask,将慢慢缩小尺寸,直到它可以放入全景图的内部
- sub,判断minRect是否全黑(0)
文章图片
全景图
文章图片
参考链接 OpenCV: samples/python/stitching.py
Image Stitching with OpenCV and Python - PyImageSearch
【OpenCV-Python|OpenCV-Python 图像全景拼接stitch及黑边处理】使用OpenCV和Python拼接图像_W_Tortoise的博客-CSDN博客
推荐阅读
- Java|Java OpenCV图像处理之SIFT角点检测详解
- ImageLoaders 加载图像
- JAVA图像处理系列(四)——噪声
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例
- 使用交叉点观察器延迟加载图像以提高性能
- Figure|Figure 图像
- 【数组题】给定一个二进制矩阵|【数组题】给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。
- FFmpeg|FFmpeg 开发(07)(FFmpeg + OpenGLES 实现 3D 全景播放器)
- opencv|图像处理之椒盐噪声的添加与去除
- ACDSee|ACDSee Photo Studio 5——数字图像处理软件