From 907ed59cd02ae4fa028e9e60d1b6d9272dfc261f Mon Sep 17 00:00:00 2001 From: Jinwei Zhao Date: Thu, 21 Jan 2016 19:54:01 +0800 Subject: add own C++ impl. --- GuidedFilter/GuidedFilter.sln | 22 +++ GuidedFilter/GuidedFilter/GuidedFilter.vcxproj | 90 +++++++++ .../GuidedFilter/GuidedFilter.vcxproj.filters | 30 +++ GuidedFilter/GuidedFilter/OpenCV3.props | 16 ++ GuidedFilter/GuidedFilter/guide.png | Bin 0 -> 389646 bytes GuidedFilter/GuidedFilter/guidedfilter.cpp | 202 +++++++++++++++++++++ GuidedFilter/GuidedFilter/guidedfilter.h | 15 ++ GuidedFilter/GuidedFilter/src.bmp | Bin 0 -> 315478 bytes GuidedFilter/GuidedFilter/test.cpp | 18 ++ 9 files changed, 393 insertions(+) create mode 100755 GuidedFilter/GuidedFilter.sln create mode 100755 GuidedFilter/GuidedFilter/GuidedFilter.vcxproj create mode 100755 GuidedFilter/GuidedFilter/GuidedFilter.vcxproj.filters create mode 100755 GuidedFilter/GuidedFilter/OpenCV3.props create mode 100755 GuidedFilter/GuidedFilter/guide.png create mode 100755 GuidedFilter/GuidedFilter/guidedfilter.cpp create mode 100755 GuidedFilter/GuidedFilter/guidedfilter.h create mode 100755 GuidedFilter/GuidedFilter/src.bmp create mode 100755 GuidedFilter/GuidedFilter/test.cpp diff --git a/GuidedFilter/GuidedFilter.sln b/GuidedFilter/GuidedFilter.sln new file mode 100755 index 0000000..c4c2744 --- /dev/null +++ b/GuidedFilter/GuidedFilter.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GuidedFilter", "GuidedFilter\GuidedFilter.vcxproj", "{7E8D3A00-45B3-448F-96C6-E5A87C57BCD3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7E8D3A00-45B3-448F-96C6-E5A87C57BCD3}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E8D3A00-45B3-448F-96C6-E5A87C57BCD3}.Debug|Win32.Build.0 = Debug|Win32 + {7E8D3A00-45B3-448F-96C6-E5A87C57BCD3}.Release|Win32.ActiveCfg = Release|Win32 + {7E8D3A00-45B3-448F-96C6-E5A87C57BCD3}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/GuidedFilter/GuidedFilter/GuidedFilter.vcxproj b/GuidedFilter/GuidedFilter/GuidedFilter.vcxproj new file mode 100755 index 0000000..2d4af0e --- /dev/null +++ b/GuidedFilter/GuidedFilter/GuidedFilter.vcxproj @@ -0,0 +1,90 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7E8D3A00-45B3-448F-96C6-E5A87C57BCD3} + Win32Proj + GuidedFilter + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/GuidedFilter/GuidedFilter/GuidedFilter.vcxproj.filters b/GuidedFilter/GuidedFilter/GuidedFilter.vcxproj.filters new file mode 100755 index 0000000..06fa319 --- /dev/null +++ b/GuidedFilter/GuidedFilter/GuidedFilter.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/GuidedFilter/GuidedFilter/OpenCV3.props b/GuidedFilter/GuidedFilter/OpenCV3.props new file mode 100755 index 0000000..1cdcd81 --- /dev/null +++ b/GuidedFilter/GuidedFilter/OpenCV3.props @@ -0,0 +1,16 @@ + + + + + + + + F:\3rdLibs\OpenCV3\opencv_build_with_contrib\install\x86\vc12\..\..\include;%(AdditionalIncludeDirectories) + + + F:\3rdLibs\OpenCV3\opencv_build_with_contrib\install\x86\vc12\lib;%(AdditionalLibraryDirectories) + opencv_calib3d300d.lib;opencv_core300d.lib;opencv_features2d300d.lib;opencv_flann300d.lib;opencv_hal300d.lib;opencv_highgui300d.lib;opencv_imgcodecs300d.lib;opencv_imgproc300d.lib;opencv_ml300d.lib;opencv_objdetect300d.lib;opencv_photo300d.lib;opencv_shape300d.lib;opencv_stitching300d.lib;opencv_superres300d.lib;opencv_ts300d.lib;opencv_video300d.lib;opencv_videoio300d.lib;opencv_videostab300d.lib;opencv_ximgproc300d.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/GuidedFilter/GuidedFilter/guide.png b/GuidedFilter/GuidedFilter/guide.png new file mode 100755 index 0000000..cbee301 Binary files /dev/null and b/GuidedFilter/GuidedFilter/guide.png differ diff --git a/GuidedFilter/GuidedFilter/guidedfilter.cpp b/GuidedFilter/GuidedFilter/guidedfilter.cpp new file mode 100755 index 0000000..92c2913 --- /dev/null +++ b/GuidedFilter/GuidedFilter/guidedfilter.cpp @@ -0,0 +1,202 @@ +#include "guidedfilter.h" + +void GuidedFilterMono(Mat guide, Mat src, Mat dst, int radius, double eps); +void GuidedFilterColor(Mat guide, Mat src, Mat dst, int radius, double eps); + +void GuidedFilter(Mat guide, Mat src, Mat dst, int radius, double eps) +{ + int depth = guide.channels(); + CV_Assert(depth == 1 || depth == 3); + + if (depth == 3) + GuidedFilterColor(guide, src, dst, radius, eps); + else if (depth == 1) + GuidedFilterMono(guide, src, dst, radius, eps); +} + +void GuidedFilterColor(Mat guide, Mat src, Mat dst, int radius, double eps) +{ + int height = src.rows; + int width = src.cols; + int widthstep = guide.step; + int gwidthstep = src.step; + int nch = guide.elemSize(); + int gnch = src.elemSize(); + + int i, j; + int m, n; + int w; + int e = 0; + int st_row, ed_row; + int st_col, ed_col; + + double sum_Ir, sum_Ig, sum_Ib; + double sum_Ir_square, sum_Ig_square, sum_Ib_square; + double sum_IrIg, sum_IgIb, sum_IrIb; + double sum_PiIr, sum_PiIg, sum_PiIb; + double sum_Pi; + + double A, B, C, D, E, F, G, H, I, J, K, L; + double X, Y, Z; + double ak_r, ak_g, ak_b; + double bk; + double det; + + double tmp_Ir, tmp_Ig, tmp_Ib; + double tmp_p, tmp_q; + + double *v_ak_r = (double *)malloc(sizeof(double) * height * width); + double *v_ak_g = (double *)malloc(sizeof(double) * height * width); + double *v_ak_b = (double *)malloc(sizeof(double) * height * width); + double *v_bk = (double *)malloc(sizeof(double) * height * width); + + int count = 0; + + uchar *data_guide = guide.data; + uchar *data_src = src.data; + uchar *data_dst = dst.data; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + st_row = i - radius, ed_row = i + radius; + st_col = j - radius, ed_col = j + radius; + + st_row = st_row < 0 ? 0 : st_row; + ed_row = ed_row >= height ? (height - 1) : ed_row; + st_col = st_col < 0 ? 0 : st_col; + ed_col = ed_col >= width ? (width - 1) : ed_col; + + sum_Ir = sum_Ig = sum_Ib = 0; + sum_Ir_square = sum_Ig_square = sum_Ib_square = 0; + sum_IrIg = sum_IgIb = sum_IrIb = 0; + sum_PiIr = sum_PiIg = sum_PiIb = 0; + sum_Pi = 0; + w = 0; + + for (m = st_row; m <= ed_row; m++) + { + for (n = st_col; n <= ed_col; n++) + { + tmp_Ib = *(data_guide + m * widthstep + n * nch); + tmp_Ig = *(data_guide + m * widthstep + n * nch + 1); + tmp_Ir = *(data_guide + m * widthstep + n * nch + 2); + + tmp_p = *(data_src + m * gwidthstep + n * gnch); + + sum_Ib += tmp_Ib; + sum_Ig += tmp_Ig; + sum_Ir += tmp_Ir; + + sum_Ib_square += tmp_Ib * tmp_Ib; + sum_Ig_square += tmp_Ig * tmp_Ig; + sum_Ir_square += tmp_Ir * tmp_Ir; + + sum_IrIg += tmp_Ir * tmp_Ig; + sum_IgIb += tmp_Ig * tmp_Ib; + sum_IrIb += tmp_Ir * tmp_Ib; + + sum_Pi += tmp_p; + sum_PiIb += tmp_p * tmp_Ib; + sum_PiIg += tmp_p * tmp_Ig; + sum_PiIr += tmp_p * tmp_Ir; + + w++; + } + } + + A = (sum_Ir_square + w * eps) * sum_Ig - sum_Ir * sum_IrIg; + B = sum_IrIg * sum_Ig - sum_Ir * (sum_Ig_square + w * eps); + C = sum_IrIb * sum_Ig - sum_Ir * sum_IgIb; + D = sum_PiIr * sum_Ig - sum_PiIg * sum_Ir; + E = (sum_Ir_square + w * eps) * sum_Ib - sum_IrIb * sum_Ir; + F = sum_IrIg * sum_Ib - sum_IgIb * sum_Ir; + G = sum_IrIb * sum_Ib - (sum_Ib_square + w * eps) * sum_Ir; + H = sum_PiIr * sum_Ib - sum_PiIb * sum_Ir; + I = (sum_Ir_square + w * eps) * w - sum_Ir * sum_Ir; + J = sum_IrIg * w - sum_Ig * sum_Ir; + K = sum_IrIb * w - sum_Ib * sum_Ir; + L = sum_PiIr * w - sum_Pi * sum_Ir; + + det = A * F * K + B * G * I + C * E * J - C * F * I - A * G * J - B * E * K; + X = D * F * K + B * G * L + C * H * J - C * F * L - D * G * J - B * H * K; + Y = A * H * K + D * G * I + C * E * L - C * H * I - D * E * K - A * G * L; + Z = A * F * L + B * H * I + D * J * E - D * F * I - B * E * L - A * H * J; + + ak_r = X / det; + ak_g = Y / det; + ak_b = Z / det; + + bk = (sum_PiIg - sum_IrIg * ak_r - (sum_Ig_square + w * eps) * ak_g - sum_IgIb * ak_b) / sum_Ig; + + tmp_Ib = *(data_guide + i * widthstep + j * nch); + tmp_Ig = *(data_guide + i * widthstep + j * nch + 1); + tmp_Ir = *(data_guide + i * widthstep + j * nch + 2); + + tmp_q = ak_b * tmp_Ib + ak_g * tmp_Ig + ak_r * tmp_Ir + bk; + tmp_q = tmp_q > 255 ? 255 : (tmp_q < 0 ? 0 : tmp_q); + + *(data_dst + i * gwidthstep + j * gnch) = cvRound(tmp_q); + + v_ak_b[count] = ak_b; + v_ak_g[count] = ak_g; + v_ak_r[count] = ak_r; + v_bk[count] = bk; + count++; + } + } + + for (int i = 0; i < height; i++) + { + for (int j = 0; j < width; j++) + { + st_row = i - radius, ed_row = i + radius; + st_col = j - radius, ed_col = j + radius; + + st_row = st_row < 0 ? 0 : st_row; + ed_row = ed_row >= height ? (height - 1) : ed_row; + st_col = st_col < 0 ? 0 : st_col; + ed_col = ed_col >= width ? (width - 1) : ed_col; + + double ak_r, ak_g, ak_b, bk; + ak_r = ak_g = ak_b = bk = 0; + + int number = 0; + for (int m = st_row; m <= ed_row; m++) + { + for (int n = st_col; n <= ed_col; n++) + { + ak_r += v_ak_r[(m) * width + n]; + ak_g += v_ak_g[(m) * width + n]; + ak_b += v_ak_b[(m) * width + n]; + bk += v_bk[(m) * width + n]; + number++; + } + } + + ak_r /= number; + ak_g /= number; + ak_b /= number; + bk /= number; + + tmp_Ib = *(data_guide + i * widthstep + j * nch); + tmp_Ig = *(data_guide + i * widthstep + j * nch + 1); + tmp_Ir = *(data_guide + i * widthstep + j * nch + 2); + + tmp_q = ak_b * tmp_Ib + ak_g * tmp_Ig + ak_r * tmp_Ir + bk; + tmp_q = tmp_q > 255 ? 255 : (tmp_q < 0 ? 0 : tmp_q); + + *(data_dst + i * gwidthstep + j * gnch) = cvRound(tmp_q); + } + } + free(v_ak_b); + free(v_ak_g); + free(v_ak_r); + free(v_bk); +} + +void GuidedFilterMono(Mat guide, Mat src, Mat dst, int radius, double eps) +{ + +} \ No newline at end of file diff --git a/GuidedFilter/GuidedFilter/guidedfilter.h b/GuidedFilter/GuidedFilter/guidedfilter.h new file mode 100755 index 0000000..1b4db66 --- /dev/null +++ b/GuidedFilter/GuidedFilter/guidedfilter.h @@ -0,0 +1,15 @@ +#ifndef GUIDED_FILTER_H +#define GUIDED_FILTER_H + +#include +#include +#include +#include + +using namespace cv; + +#include + +void GuidedFilter(Mat guide, Mat src, Mat dst, int radius, double eps); + +#endif diff --git a/GuidedFilter/GuidedFilter/src.bmp b/GuidedFilter/GuidedFilter/src.bmp new file mode 100755 index 0000000..58d8485 Binary files /dev/null and b/GuidedFilter/GuidedFilter/src.bmp differ diff --git a/GuidedFilter/GuidedFilter/test.cpp b/GuidedFilter/GuidedFilter/test.cpp new file mode 100755 index 0000000..e0dc95d --- /dev/null +++ b/GuidedFilter/GuidedFilter/test.cpp @@ -0,0 +1,18 @@ +#include "guidedfilter.h" + +int main() +{ + Mat src = imread("src.bmp", IMREAD_GRAYSCALE); + Mat guide = imread("guide.png"); + Mat dst_own(src.rows, src.cols, CV_8UC1, Scalar(0)); + Mat dst_opencv(src.rows, src.cols, CV_8UC1, Scalar(0)); + + GuidedFilter(guide, src, dst_own, 3, 1e-6); + imwrite("own.bmp", dst_own); + + cv::ximgproc::guidedFilter(guide, src, dst_opencv, 3, 1e-6); + imwrite("opencv.bmp", dst_opencv); + + printf("Done"); + return 0; +} \ No newline at end of file -- cgit v1.2.3