使用OpenCV和Python提取地板布局遮罩

问题描述 投票:0回答:1

我尝试使用SSIM提取两个图像之间的差异,并获取照片上的地板面积以估算image_b的地板布局质量。

我期望的输出是一个阈值(代表地板布局的两个图像之间的差异)。

我遇到的问题是,由于对image_b应用了未知的滤镜/调整大小算法,因此阈值不正确。有时在非地面区域会发现人口。而且cv2.findContours() max(contour_sizes, key=lambda x: x[0])都不足以获取所有楼层像素,因为并非所有楼层面积都被封闭或相交。

[我所需要做的是从图像中提取地板面积,即从差异阈值中找到all“地板轮廓”,并用白色绘制缺失的像素。

from skimage.measure import compare_ssim
import cv2
...

image_a = cv2.imread(first)
image_b = cv2.imread(second)

gray_a = cv2.cvtColor(image_a, cv2.COLOR_BGR2GRAY)
gray_b = cv2.cvtColor(image_b, cv2.COLOR_BGR2GRAY)

score, diff = compare_ssim(gray_a, gray_b, full=True, gaussian_weights=True)
diff = (diff * 255).astype("uint8")

thresh = cv2.threshold(diff, 0, 255,
                       cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]


if len(contour_sizes) > 0:
    largest_contour = max(contour_sizes, key=lambda x: x[0])[1]
    x, y, w, h = cv2.boundingRect(largest_contour)
    cv2.rectangle(image_a, (x, y), (x + w, y + h), (36, 255, 12), 2)
    cv2.rectangle(image_b, (x, y), (x + w, y + h), (36, 255, 12), 2)

cv2.imwrite('image_a.jpg', image_a)
cv2.imwrite('image_b.jpg',image_b)
cv2.imwrite('thresh.jpg', thresh)

已检测到最大轮廓的image_aenter image description here检测到最大轮廓的image_benter image description here脱粒enter image description here

python image opencv ssim
1个回答
0
投票

通过对图像之间的差异平均值进行阈值可以获得更好的结果。

def get_mask(img1, img2, thresh):
    if img1.shape != img2.shape:
        return
    diff = cv2.absdiff(img1, img2)
    diff = np.mean(diff, axis=2)
    diff[diff <= thresh] = 0
    diff[diff > thresh] = 255
    mask = np.dstack([diff] * 3)
    return mask

thresh_morph

伪像可能出现在生成的蒙版中,并且可以通过应用Morphological Transformations来减少。

© www.soinside.com 2019 - 2024. All rights reserved.