【问题标题】:How to find the Gaussian Weighted-Average and Standard deviation of a structural element如何找到结构元素的高斯加权平均值和标准差
【发布时间】:2017-07-04 12:51:07
【问题描述】:

我正在尝试实现由以下公式描述的强度归一化算法:

x' = (x - gaussian_weighted_average) / std_deviation

我正在阅读的论文描述了我必须使用 7x7 内核找到每个像素“x”邻居对应的高斯加权平均值和标准偏差。

PS:x'是新的像素值。

所以,我的问题是:如何使用 7x7 内核计算图像中每个像素的高斯加权平均值和标准差?

OpenCV 有没有提供解决这个问题的方法?

import cv2
img = cv2.imread("b.png", 0)
widht = img.shape[0]
height = img.shape[1]
for i in range (widht):
    for j in range (height):
        new_image = np.zeros((height,width,1), np.uint8)
        new_image[i][j] = img[i][j] - ...

【问题讨论】:

标签: python opencv image-processing


【解决方案1】:

作者的原始实现(C++)可以找到here:见GenerateIntensityNormalizedDatabase()

这已被另一位 Python 学生重新实现。 python的实现是:

import cv2
import numpy as np

def StdDev(img, meanPoint, point, kSize):
    kSizeX, kSizeY = kSize / 2, kSize / 2

    ystart = point[1] - kSizeY if 0 < point[1] - kSizeY < img.shape[0] else 0
    yend = point[1] + kSizeY + 1 if 0 < point[1] + kSizeY + 1 < img.shape[0] else img.shape[0] - 1

    xstart = point[0] - kSizeX if 0 < point[0] - kSizeX < img.shape[1] else 0
    xend = point[0] + kSizeX + 1 if 0 < point[0] + kSizeX + 1 < img.shape[1] else img.shape[1] - 1

    patch = (img[ystart:yend, xstart:xend] - meanPoint) ** 2
    total = np.sum(patch)
    n = patch.size

    return 1 if total == 0 or n == 0 else np.sqrt(total / float(n))


def IntensityNormalization(img, kSize):
    blur = cv2.GaussianBlur(img, (kSize, kSize), 0, 0).astype(np.float64)
    newImg = np.ones(img.shape, dtype=np.float64) * 127

    for x in range(img.shape[1]):
        for y in range(img.shape[0]):
            original = img[y, x]
            gauss = blur[y, x]
            desvio = StdDev(img, gauss, [x, y], kSize)

            novoPixel = 127
            if desvio > 0:
                novoPixel = (original - gauss) / float(desvio)

            newVal = np.clip((novoPixel * 127 / float(2.0)) + 127, 0, 255)
            newImg[y, x] = newVal
    return newImg

要使用强度归一化,您可以这样做:

kSize = 7
img = cv2.imread('{IMG_FILENAME}', cv2.IMREAD_GRAYSCALE).astype(np.float64)
out = IntensityNormalization(img, kSize)

要可视化生成的图像,请不要忘记将 out 转换回 np.uint8 (why?)。如果你想重现他的结果,我建议你使用 C++ 中的原始实现。

免责声明:我来自此paper 的作者的同一lab

【讨论】:

  • 提供的代码不会将输入图像从 OP 映射到所需的结果 (i.imgur.com/oZcqdXR.jpg)
  • 提示:将内核大小更改为 15,25。
  • @Oxydron 是的。您必须根据输入大小调整内核大小。
猜你喜欢
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
相关资源
最近更新 更多