GIMP difference of Gaussians in Opencv

牧云@^-^@ 提交于 2019-12-24 13:02:25

问题


I want to replicate the GIMP Filter > Edge Decect > Difference of Gaussians in C++ using opencv.

I found this simple code for DOG implementation bu I want the same result of GIMP with the two params Raidus1 and Radius2.

Mat g1, g2, result;
Mat img = imread("test.png", CV_LOAD_IMAGE_COLOR); 
GaussianBlur(img, g1, Size(1,1), 0);
GaussianBlur(img, g2, Size(3,3), 0);
result = g1 - g2;

How can add the 2 radius params to the implementation?

Sample input image

Params

Output

If can help this is the link to the C implementation of the filter

https://gitlab.gnome.org/GNOME/gimp/blob/master/plug-ins/common/edge-dog.c


回答1:


I don't have the answer, but have run out of hair - see comment. I have been working on this and have some code that doesn't work, but somebody cleverer than me who doesn't feel like writing code, may be able to see what is wrong, so I thought I would share what I have. I am not interested in any points, so anyone is welcome to take and adapt this and show a working answer. Fine by me if we find a solution. I did it in Python but I am sure we can easily adapt any Python to C++ if we get something that works.

#!/usr/bin/env python3

import numpy as np
import math
import cv2

def radius2stdev(radius):
    """
    Return std deviation corresponding to a given radius.
    I got this from: https://gitlab.gnome.org/GNOME/gimp/blob/master/plug-ins/common/edge-dog.c
    """
    stdev  = math.sqrt (-(radius * radius) / (2 * math.log (1.0 / 255.0)));
    return stdev

# Load image, make float and scale to range 0..1
im = cv2.imread("image.jpg",cv2.IMREAD_COLOR).astype(np.float)
im = im/255.0

stdev1  = radius2stdev(22.0)
stdev2  = radius2stdev(5.0)

print('Stdev1: {}'.format(stdev1))
print('Stdev2: {}'.format(stdev2))

# Generate the two Gaussians and their difference
# I believe OpenCV calculates the size of the kernel to match the std dev if you pass no kernel size
# See https://docs.opencv.org/3.4.1/d4/d86/group__imgproc__filter.html#gaabe8c836e97159a9193fb0b11ac52cf1

g1 = cv2.GaussianBlur(im,(0,0),stdev1,stdev1)
g2 = cv2.GaussianBlur(im,(0,0),stdev2,stdev2)
result = g1 -g2

# Multiply back up by 255 and save as PNG
result = (result * 255).astype(np.uint8)
cv2.imwrite("result.png", result)

# Normalize and save normalised too
resultn = cv2.normalize(result,None,alpha=0,beta=255,norm_type=cv2.NORM_MINMAX)
cv2.imwrite("result-n.png", resultn)

The standard deviations are printed out like this:

Stdev1: 6.608505869104614
Stdev2: 1.5019331520692305

I believe the 22,000 and 5,000 shown for your radii are just a result of your internationalisation and these correspond to 22.0 and 5.0 in US/UK format.


I also had an attempt with ImageMagick on the command-line and got something vaguely similar though I am not sure what that proves:

magick image.jpg -morphology Convolve DoG:0,20,5 -evaluate multiply 6 result.jpg




回答2:


It looks like missing a line. From lines 729-730 of edge-dog.c:

  radius = fabs (radius) + 1.0;
  std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

Gimp then computes the Gaussian as list of integers in make_curve(std_dev, ...). Note



来源:https://stackoverflow.com/questions/54970035/gimp-difference-of-gaussians-in-opencv

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!