0

I wrote some Gaussian filter code, however it doesn't look like OpenCV's GaussianBlur with the same parameters:

#!/usr/bin/env python3

import numpy as np
import math
import cv2


def get_raw_data(image_dims, rescale_factor=5):
    img = np.random.rand(
        image_dims[0] // rescale_factor, image_dims[1] // rescale_factor, 1)
    return cv2.resize(img, (0, 0),
                      fx=rescale_factor, fy=rescale_factor,
                      interpolation=cv2.INTER_NEAREST)


def psf(diameter):
    radius = diameter / 2
    kernel = np.zeros((diameter, diameter, 1), dtype="float")
    for i in range(-diameter // 2, diameter // 2 + 1):
        for j in range(-diameter // 2, diameter // 2 + 1):
            new_val = normal_pdf(i, 0, radius) * \
                normal_pdf(j, 0, radius)
            kernel[i + diameter // 2, j + diameter // 2] = new_val
    return kernel


def normal_pdf(x, m, s):
    inv_sqrt_2pi = 0.3989422804014327
    a = (x - m) / s
    return inv_sqrt_2pi / s * math.exp(-0.5 * a * a)


def main():
    print(psf(5))
    raw_data = get_raw_data((50, 100))
    blurred = cv2.filter2D(raw_data, -1, psf(5))
    cv2.imshow("raw", cv2.resize(raw_data,
                                 (1800, 900),
                                 interpolation=cv2.INTER_NEAREST))
    cv2.waitKey()
    cv2.imshow("blurred", cv2.resize(blurred,
                                     (1800, 900),
                                     interpolation=cv2.INTER_NEAREST))
    cv2.waitKey()
    blurred = cv2.GaussianBlur(raw_data, (5, 5), 0, 0)
    cv2.imshow("blurred", cv2.resize(blurred,
                                     (1800, 900),
                                     interpolation=cv2.INTER_NEAREST))
    cv2.waitKey()

if __name__ == '__main__':
    main()

For the most part, it looks like my blurred image is darker than the image that OpenCV generates. I suspect that there's something wrong with how I'm calculating the PSF, but I'm not sure what I'm doing wrong.

EDIT: Replacing blurred = cv2.GaussianBlur(raw_data, (5, 5), 0, 0) with blurred = cv2.GaussianBlur(raw_data, (5, 5), 5, 5) helped, although my blur still produces a darker value than OpenCV's.

AnimatedRNG
  • 1,859
  • 3
  • 26
  • 39
  • You can get and compare the two gaussian kernels by applying the blurr on an image with a single white pixel on a black background, that may help you spot what's wrong. – jadsq Jul 18 '17 at 16:10
  • 1
    @jadsq Or perhaps just use [`getGaussianKernel`](http://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html#getgaussiankernel)? – Dan Mašek Jul 18 '17 at 18:31
  • 1
    For one your OpenCV `GaussianBlur` has a stddev of 0 (I still don't understand why this is allowed, I should dig around a bit) while your PDF has a stddev of 5. You're confusing the radius and the stddev. For two (stemming from the same issue), you're using an continuous PDF for your own blur, but OpenCV uses a truncated discrete PDF. – alkasm Jul 18 '17 at 20:51
  • @AlexanderReynolds For what I need it for, the standard deviation just needs to scale with the radius. Good catch regarding exactly how `sigmaX` and `sigmaY` are computed from `ksize`. However after supplying the radius as the stddev, it still looks darker than the OpenCV result. – AnimatedRNG Jul 18 '17 at 22:12
  • @DanMašek Good idea; I'm going to compare the getGaussianKernel kernel against mine and see what's different – AnimatedRNG Jul 18 '17 at 22:16
  • Your kernel should sum to 1.0, does it? If it doesn't it needs to be scaled, otherwise the image brightness will change - if less than 1.0 it will get darker, if greater than 1.0 it will get brighter. – Mark Ransom Jul 18 '17 at 22:18
  • @MarkRansom It doesn't sum to 1.0. If I rescale it so that it *does* sum to 1.0, the resulting image looks virtually identical to the OpenCV gaussian blur, however, the kernels are not identical – AnimatedRNG Jul 18 '17 at 22:43
  • Ah, I think the issue is that I'm using a continuous gaussian distribution rather than a discrete gaussian distribution.... – AnimatedRNG Jul 18 '17 at 22:48
  • Good! That means you're halfway there. Unfortunately I don't know how OpenCV calculates its kernels so I can't help beyond that. – Mark Ransom Jul 18 '17 at 22:49
  • I'm curious why my rescaled image *is* identical to OpenCV's – AnimatedRNG Jul 18 '17 at 22:52

0 Answers0