Filtr średni/SD OpenCV

Rzucam to tam w nadziei, że ktoś będzie próbował coś tak śmiesznego wcześniej. Moim celem jest pobranie obrazu wejściowego i segmentacja go na podstawie odchylenia standardowego małego okna wokół każdego piksela. Zasadniczo powinno to matematycznie przypominać filtr Gaussa lub pola, w tym, że zostanie zastosowane do czasu kompilacji (lub nawet czasu wykonania) określonego przez użytkownika rozmiaru okna wokół każdego piksela, a tablica docelowa będzie zawierać informacje SD w każdym pikselu, w obraz tego samego rozmiaru co oryginał.

Chodzi o to, aby zrobić to na obrazie w przestrzeni HSV, aby łatwo znaleźć obszary jednorodnego koloru (tj. te z małymi lokalnymi kartami SDs w płaszczyźnie odcienia i Sat) i wyodrębnić je z obrazu w celu bardziej szczegółowego przetwarzania.

Pytanie brzmi, czy ktoś kiedyś zbudował taki niestandardowy filtr? Nie wiem jak zrobić SD w prostym polu typu filter kernel jak te używane do Gaussa i rozmycia, więc zgaduję, że będę musiał użyj konstrukcji FilterEngine. Zapomniałem też wspomnieć, że robię to w C++.

Twoje rady i przemyślenia są bardzo mile widziane.

Author: gankoji, 2012-07-12

1 answers

Wikipedia ma ładne Wyjaśnienieodchylenia standardowego , które można wykorzystać do filtrowania odchylenia standardowego.

Zasadniczo sprowadza się to do rozmycia obrazu filtrem pudełkowym, rozmycia kwadratu obrazu filtrem pudełkowym i wzięcia pierwiastka kwadratowego ich różnicy.

UPDATE: jest to prawdopodobnie lepiej pokazane z równaniem z Wikipedii... Tutaj wpisz opis obrazka

Możesz myśleć o funkcji OpenCV blur jako reprezentującej oczekiwane wartość (tj. E[X] a.k.a. średnia próbki) sąsiedztwa zainteresowania. Losowe próbki X w tym przypadku są reprezentowane przez piksele obrazu w okolicy lokalnej. Dlatego używając powyższej równoważności mamy coś w rodzaju sqrt(blur(img^2) - blur(img)^2) w OpenCV. W ten sposób można obliczyć średnie lokalne i odchylenia standardowe.

Na wszelki wypadek, gdybyś był ciekaw matematycznego dowodu. Równoważność ta jest znana jako wzór obliczeniowy dla wariancja . Oto jak możesz to zrobić w OpenCV:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

Mat mat2gray(const Mat& src)
{
    Mat dst;
    normalize(src, dst, 0.0, 1.0, NORM_MINMAX);
    return dst;
}

int main()
{
    Mat image = imread("coke-can.jpg", 0);

    Mat image32f;
    image.convertTo(image32f, CV_32F);

    Mat mu;
    blur(image32f, mu, Size(3, 3));

    Mat mu2;
    blur(image32f.mul(image32f), mu2, Size(3, 3));

    Mat sigma;
    cv::sqrt(mu2 - mu.mul(mu), sigma);

    imshow("coke", mat2gray(image32f));
    imshow("mu", mat2gray(mu));
    imshow("sigma",mat2gray(sigma));
    waitKey();
    return 0;
}

Daje to następujące obrazy:

Oryginał

Tutaj wpisz opis obrazka

Średnia

Tutaj wpisz opis obrazka

Odchylenie Standardowe

Tutaj wpisz opis obrazka

Mam nadzieję, że to pomoże!
 29
Author: mevatron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-16 01:03:25