首页 > 解决方案 > OpenCV 图像校正以填充图像中的空白和孔洞

问题描述

我目前正在从事一个带有平面图图像的项目。我正在处理一个有一定输出的问题,但通常需要进行一些修正。这就是我所拥有的:

上图是预测输出,下图是地面实况。例如,纠正缺少黑色填充物的斑点的最佳方法是什么?

在此处输入图像描述

标签: pythonimageopencvimage-processingcomputer-vision

解决方案


一个想法是通过巧妙的技巧使用形态变换。如果您只是使用正常的变形闭合来填充孔,由于墙壁的末端弯曲,它不会起作用。因此,为了解决这个问题,我们可以通过首先检测所有水平墙,然后一次检测一个垂直墙,将墙分成两部分。一旦我们隔离了每个方向,我们就会找到矩形轮廓,它将有效地创建墙的角点。这是一个可视化:

输入图像

检测到由矩形填充绘制的水平和垂直墙壁

组合口罩

输入图像上的颜色蒙版以获得结果

这是第二个输入图像的结果

代码

import cv2
import numpy as np

# Load image, create mask, grayscale, and Otsu's threshold
image = cv2.imread('2.png')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Perform morph operations
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, open_kernel, iterations=1)
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, close_kernel, iterations=3)

# Find horizontal sections and draw rectangle on mask 
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,3))
detect_horizontal = cv2.morphologyEx(close, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(mask, (x, y), (x + w, y + h), (255,255,255), -1)
    cv2.rectangle(mask, (x, y), (x + w, y + h), (255,255,255), 2)

# Find vertical sections and draw rectangle on mask 
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,25))
detect_vertical = cv2.morphologyEx(close, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(mask, (x, y), (x + w, y + h), (255,255,255), -1)
    cv2.rectangle(mask, (x, y), (x + w, y + h), (255,255,255), 2)

# Color mask onto original image
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
image[mask==255] = [0,0,0]

cv2.imshow('opening', opening)
cv2.imshow('close', close)
cv2.imshow('image', image)
cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.waitKey()

推荐阅读