【问题标题】:How to calculate the variance of an image excluding a list of circles如何计算不包括圆列表的图像的方差
【发布时间】:2019-12-12 12:37:13
【问题描述】:

我有一个灰度图像和一个圆圈列表,我正在尝试计算图像的方差,同时排除位于其中一个圆圈内的任何像素。

我当前的实现非常慢(循环遍历图像并检查每个像素是否在其中一个圆圈内)。

我尝试将圆圈设置为图像的平均值(以消除它们对方差的影响),但这会产生不同的结果,因为平均值是在原始图像上计算的。

我能做些什么来让它更有效地运行?

def variance_without_circles(image, circles):
    mean = 0
    sum_squared = 0
    count = 0
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            if is_in_circles(circles, i, j):
                continue
            else:
                count += 1
                val = image[i, j]
                mean += val
                sum_squared += val ** 2
    mean = mean / count
    variance = sum_squared / count - mean ** 2
    return variance
def is_in_circles(circles, i, j):
    for c in circles[0]:
        if (c[0] - j)**2 + (c[1] - i)**2 < (c[2] ** 2):
            return True
    return False

【问题讨论】:

  • 我认为如果您提供逼真的图像和现实的圆圈列表会有所帮助,以便我们知道我们在处理什么!如果做不到这一点,请复制图像并用黑色填充,即mask = np.zeros_like(image),然后用白色绘制圆圈并计算方差的掩码数组。
  • 酷 - 您可以将其添加为答案并自己接受(在 SO 上完全允许),以便其他人可以找到并查看正确答案,并且您可以获取积分。做得好,谢谢分享。

标签: python numpy computer-vision


【解决方案1】:

您可以将所有圆圈绘制到二进制蒙版上,然后使用此蒙版来索引您的图像并仅计算输入图像上此切片部分的方差。

例如:

from collections import namedtuple

import cv2
import numpy as np

Circle = namedtuple('Circle', ['cx', 'cy', 'radius'])

image = cv2.imread('lena.png', cv2.IMREAD_COLOR)
print(f'Variance (whole): {np.var(image)}')

circles = [
    Circle(cx=45, cy=23, radius=31),
    Circle(cx=321, cy=111, radius=89),
    Circle(cx=465, cy=511, radius=67)
]

circles_mask = np.full(shape=(image.shape[0], image.shape[1]), fill_value=255, dtype=np.uint8)
for circle in circles:
    cv2.circle(circles_mask, (circle.cx, circle.cy), radius=circle.radius,
               color=(0, 0, 0), thickness=cv2.FILLED)

image_masked = image[np.where(circles_mask)]
print(f'Variance (masked): {np.var(image_masked)}')

cv2.imshow('image', image)
cv2.imshow('circles_mask', circles_mask)
cv2.waitKey(0)

用于测试的图片:

圆圈掩码:

【讨论】:

  • 谢谢,当我找到 namedtuple 的用例时,我总是很高兴:D
【解决方案2】:

根据 Mark Setchel 的评论,我使用了 numpy 的 masked_array

创建一个黑色蒙版并将圆圈涂成白色。然后计算掩码数组上的方差:

def variance_without_circles(image, circles):
    mask = np.zeros_like(image)
    for c in circles[0]:
        cv2.circle(mask, (c[0], c[1]), c[2], 255, -1, 8)
    masked_image = np.ma.masked_array(image, mask)
    return masked_image.var()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-05
    • 2013-02-27
    • 1970-01-01
    • 2021-03-16
    • 2015-05-09
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    相关资源
    最近更新 更多