Przetwarzam pliki obrazów ze zmierzeniemintensywność, w zasadzie wydobywanie wokseli w rozmiarach 1x1x1 pikseli. Pliki obrazów tworzą wolumin, aby uniknąć intensywności pików. Chciałbym znaleźć sposób na średnie 3x3x3 piksele.
Mój problem polega na tym, aby zrozumieć problem, ponieważ jest to kształt w obrazie oddzielony zerami i innymi wartościami. Tak więc najpierw rozważałem for
-lukaj z if
-komunikat. Są to rozważania, które poczyniłem do tej pory for
-loop i if
-komunikat. MATLAB postrzega głośność jako długą matrycę, a więc prostą for
Pętla powinna być łatwa do znalezienia niezerowej wartości i sąsiednich wartości, i przyjąć średnią ponad te wartości. Problem pojawia się, gdy muszę wziąć pod uwagę wymiar z.
To najwyraźniej nie działa optymalnie i ciężko mi wyjaśnić efekty graniczne.
Odpowiedzi:
6 dla odpowiedzi № 1Mam nadzieję, że poprawnie interpretuję twoje pytanie, alechcesz znaleźć średnią dla objętości woksela 3 x 3 x 3 dla każdego woksela w obrazie wejściowym, w którym każdy woksel wejściowy działa jako środek każdej objętości woksela 3 x 3 x 3 do uśrednienia. Jeśli masz możliwość korzystania z wbudowanych funkcji MATLAB, rozważ użycie splotu N-D z convn
. Nie używaj tutaj pętli, ponieważ będzie to bardzo powolne convn
, pierwszym parametrem jest obraz 3D, adrugim parametrem jest jądro 3 x 3 x 3 o wartościach równych 1/27. Masz również możliwość określenia, co stanie się wzdłuż granicy, jeśli jądro splotu wykracza poza granice obrazu wejściowego. Zwykle chcesz zwrócić obraz wyjściowy o takim samym rozmiarze jak dane wejściowe, a więc możesz chcieć określić "same"
flag jako trzeci opcjonalny parametr. Ten mechanizm uśredniający zakłada również, że zewnętrzne krawędzie są wyściełane zerami.
Dlatego zakładaj, że twój obraz jest zapisany im
, zrób coś takiego:
%// Create kernel of all 1/27 in a 3 x 3 x 3 matrix
kernel = ones(3,3,3);
kernel = kernel / numel(kernel);
%// Perform N-D convolution
out = convn(double(im), kernel, "same"); %// Cast to double for precision
out = cast(out, class(im)); %// Recast back to original data type
Ewentualnie, jeśli masz dostęp do przybornika do przetwarzania obrazu, użyj imfilter
zamiast. Różnica z tym i convn
czy to imfilter
został napisany przy użyciu Zintegrowane prymitywy wydajności Intel (IIPP), więc wydajność zdecydowanie będzie większa:
%// Create kernel of all 1/27 in a 3 x 3 x 3 matrix
kernel = ones(3,3,3);
kernel = kernel / numel(kernel);
%// Perform N-D convolution
out = imfilter(im, kernel);
Dodatkową korzyścią jest to, że nie musisz zmieniać typu wejścia. imfilter
automatycznie podsuwa to, przetwarza z zachowaniem oryginalnego typu obrazu wejściowego i typu wyjściowego imfilter
jest taki sam jak typ wejścia. Z convn
, przed użyciem należy upewnić się, że dane są zmiennoprzecinkowe.