Cześć, zacząłem bawić się w openCV, napisałem filtr Kuwahara, problem w tym, że bardzo długo się ładuje, około 10 sekund w debugu i ok. 1/2 w release w porównaniu z gotowcem z biblioteki.
Tutaj obrazuje działanie filtru: KLIK
Tyle że to jeden obrazek no i nie wyobrażam sobie detekcji w ruchu używając tego filtru na obrazie z kamery.
Jeżeli jest taka możliwość to prosiłbym o pomoc i ew. wytknięcie błędów w celu skróceniu czasu działania.
Jest to mój najdłuższy algorytm, jaki do tej pory napisałem no i nie mam doświadczenia w optymalizacji.
#include"opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
inline float variance(cv::Mat& mat, float mean)
{
float var = 0;
for (uchar &p : cv::Mat_<uchar>(mat))
var += pow(p - mean, 2);
return sqrt(var / (mat.size().height * mat.size().width));
}
inline float mean(cv::Mat& mat)
{
float mean = 0;
for (uchar &p : cv::Mat_<uchar>(mat))
mean += static_cast<float>(p);
return mean / (mat.size().height * mat.size().width);
}
void kuwaharaFiltering(cv::Mat& mat, int m)
{
if (m % 2 - 1)
return;
cv::Size mask(m, m); // tworzenie kwadratowej maski
cv::Size imgSize = mat.size();
cv::Size moves(imgSize.width - mask.width, imgSize.height - mask.height); // ilosc ruchów = rozmiar obrazu - rozmiar maski
cv::Size regionSize = mask / 2;
regionSize.height += 1, regionSize.width += 1; // rozmiar regionu = (rozmiar maski / 2) + 1
//[1region][2region]
//[3region][4region]
for (int i = 0; i <= moves.height; i++)
{
for (int j = 0; j <= moves.width; j++)
{
cv::Mat region1(mat, cv::Rect(
j, i, // punkt poczatku wycinania
regionSize.height, regionSize.width)); // dlugosc/szerokosc wycinania
float mean1 = mean(region1);
float var1 = variance(region1, mean1);
cv::Mat region2(mat, cv::Rect(
mask.width - regionSize.width + j, i,
regionSize.height, regionSize.width));
float mean2 = mean(region2);
float var2 = variance(region2, mean2);
cv::Mat region3(mat, cv::Rect(
j, mask.height - regionSize.height + i,
regionSize.height, regionSize.width));
float mean3 = mean(region3);
float var3 = variance(region3, mean3);
cv::Mat region4(mat, cv::Rect(
mask.width - regionSize.width + j, mask.height - regionSize.height + i,
regionSize.height, regionSize.width));
float mean4 = mean(region4);
float var4 = variance(region4, mean4);
if (var1 < var2 && var1 < var3 && var1 < var4)
mat.at<uchar>((mask.height / 2) + i, (mask.height / 2) + j) = mean1;
else if (var2 < var1 && var2 < var3 && var2 < var4)
mat.at<uchar>((mask.height / 2) + i, (mask.height / 2) + j) = mean2;
else if (var3 < var1 && var3 < var2 && var3 < var4)
mat.at<uchar>((mask.height / 2) + i, (mask.height / 2) + j) = mean3;
else if(var4 < var1 && var4 < var2 && var4 < var3)
mat.at<uchar>((mask.height / 2) + i, (mask.height / 2) + j) = mean4;
}
}
}
int main()
{
cv::Mat greyScaleImg;
cv::Mat KuwaharaFilter;
cv::namedWindow("Base");
cv::namedWindow("Kuwahara Filter");
KuwaharaFilter = cv::imread("D:/C++/openCV/lena.jpg");
cv::cvtColor(KuwaharaFilter, greyScaleImg,cv::ColorConversionCodes::COLOR_RGB2GRAY);
KuwaharaFilter = greyScaleImg.clone();
kuwaharaFiltering(KuwaharaFilter, 5);
cv::imshow("Base", greyScaleImg);
cv::imshow("Kuwahara Filter", KuwaharaFilter);
cv::waitKey();
}