Разница GIMP гауссиан в Opencv - PullRequest
0 голосов
/ 03 марта 2019

Я хочу скопировать фильтр GIMP> Обрамление края> Разница по Гауссу в C ++, используя opencv.

Я нашел этот простой код для реализации DOG, но я хочу получить тот же результат GIMP с двумя параметрами Raidus1 иРадиус2.

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;

Как добавить 2 параметра радиуса к реализации?

Образец входного изображения enter image description here

Параметры enter image description here

Выход enter image description here

Если может помочь, это ссылка на реализацию фильтра C

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

1 Ответ

0 голосов
/ 03 марта 2019

У меня нет ответа, но кончились волосы - см. Комментарий.Я работал над этим и у меня есть код, который не работает, но кто-то умнее меня, который не хочет писать код, может увидеть, что не так, поэтому я решил поделиться тем, что у меня есть.Меня не интересуют какие-либо вопросы, поэтому любой может принять и адаптировать это и показать рабочий ответ.Хорошо, если мы найдем решение.Я сделал это на Python, но я уверен, что мы можем легко адаптировать любой Python к C ++, если мы получим что-то, что работает.

#!/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)

Стандартные отклонения распечатываются так:

Stdev1: 6.608505869104614
Stdev2: 1.5019331520692305

Я считаю, что 22000 и 5000, показанные для ваших радиусов, являются просто результатом вашей интернационализации, и они соответствуют 22.0 и 5.0 в формате США / Великобритании.


У меня также была попытка ImageMagick в командной строке и получил что-то неопределенно похожее, хотя я не уверен, что это доказывает:

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

enter image description here

...