如何用Python/OpenCV裁剪图像以去除无效空白区域
背景
我正在使用SIFT和ANN将多张图像拼接成网格(本文为2×2网格)。当所有图像的方向、平移缩放因子一致时,拼接效果完美:
- 输入图像:4张规整的待拼接图像
- 拼接后的灰度图像:无黑边的完整拼接结果
但当对图像进行平移操作时(实际数据集无法保证图像完全规整),即使仅平移1像素,拼接图像中就会出现大量黑边:
- 左上角图像沿x、y方向平移20像素后,拼接结果出现厚度为20像素的粗水平黑边
- 左上角与右上角图像沿x、y方向平移5像素后,拼接结果出现厚度5像素的垂直黑边和厚度1像素的水平黑边
已尝试方案
经排查,黑边是图像平移导致部分区域丢失,现有裁剪算法将这些缺失区域保留为黑色。我的拼接逻辑是先横向拼接所有图像,再纵向拼接,前一步产生的空白区域会被带入最终结果——比如第一次迭代拼接出的顶部图像,底部保留了空白区域。
我尝试用以下代码去除拼接缝和多余空白:
# CLEAN UP IMAGE: The following code will clean up the merged image, removing any seams that may arise, ensuring the image stays grayscale, and cropping the image to scale. def CleanImage(result): # Remove Seams, Ensure Grayscale, Crop Image to Scale # grayscale images finalG = result thresh = cv.threshold(finalG, 0, 255, cv.THRESH_BINARY|cv.THRESH_OTSU)[1] #OTSU's binarization determines the best value to separate the peaks as certain pixels/colors appear cnts = cv.findContours(thresh.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) print(cnts) cnts = imutils.grab_contours(cnts) print("Contours", len(cnts)) # find maximum contour area c = max(cnts, key=cv.contourArea) (x, y, w, h) = cv.boundingRect(c) # crop image to smallest box coordinates finalG = finalG[y:y + h, x:x + w] cnts = cv.findContours(thresh.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) #output final result printF(finalG) return finalG
问题在于这段代码基于最大轮廓的外接矩形坐标裁剪,若图像仅单侧丢失部分区域,仍会保留无效空白。
我的问题
如何精准裁剪图像以去除无效空白区域(例如根据目标边缘坐标裁剪)?或者是否有更优解决方案?
非常感谢!
算法其余代码(上下文)
def runAlgo(ImgArray): while (len(ImgArray) >= 2): (kpsA, featuresA, annoImgA) = SIFTAlgo(ImgArray[0]) (kpsB, featuresB, annoImgB) = SIFTAlgo(ImgArray[1]) matches = ANN(annoImgA, annoImgB, featuresA, featuresB, kpsA, kpsB) H = Homography(kpsA, kpsB, featuresA, featuresB, matches) result = CreateImage(ImgArray[0], ImgArray[1], H) finalG = CleanImage(result) ImgArray.pop(0) ImgArray[0] = finalG return ImgArray
#main rows = int(input("Please insert number of rows: ")) columns = int(input("Please insert number of columns: ")) readIm() # printIm(Images) for row in range(rows): newImages = [] for col in range(columns): newImages.append(Images[0]) Images.pop(0) runAlgo(newImages) finalImages.append(newImages[0]) for row in range(rows): runAlgo(finalImages) printIm(finalImages)
内容的提问来源于stack exchange,提问作者Hana
相关产品推荐
相关产品推荐

