From 2b550c2f63ebe553b61457488d0bb0bc0a324850 Mon Sep 17 00:00:00 2001 From: meshtag Date: Tue, 12 Jan 2021 17:33:01 +0530 Subject: [PATCH 01/14] Added all standard morphological transformations --- example/morphology.cpp | 175 +++++++++++++++++++++++++++++++++++++++++ example/original.png | Bin 0 -> 2082 bytes 2 files changed, 175 insertions(+) create mode 100644 example/morphology.cpp create mode 100644 example/original.png diff --git a/example/morphology.cpp b/example/morphology.cpp new file mode 100644 index 0000000000..27acd6d795 --- /dev/null +++ b/example/morphology.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include + +boost::gil::gray8_image_t img; + +//This function is used for applying basic threshold and convolution operations which are applied +//under the hood for all morphological transformations. +template +boost::gil::gray8_image_t thresh_con_thresh(SrcView const& src_view, Kernel const& ker_mat,const int threshold1,const int threshold2) +{ + using namespace boost::gil; + boost::gil::gray8_image_t intermediate_img(src_view.dimensions()); + threshold_binary(src_view, view(intermediate_img),threshold1, 255); + detail::convolve_2d(view(intermediate_img), ker_mat, view(intermediate_img)); + threshold_binary(const_view(intermediate_img),view(intermediate_img),threshold2,255); + return intermediate_img; +} + +template +boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat,const int iterations) +{ + boost::gil::gray8_image_t img_out_dilation(src_view.dimensions()); + img_out_dilation = img; + for(int i=0;i +boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,const int iterations) +{ + boost::gil::gray8_image_t img_out_erosion(src_view.dimensions()); + img_out_erosion = img; + for(int i=0;i +boost::gil::gray8_image_t opening(SrcView const& src_view, Kernel const& ker_mat) +{ + boost::gil::gray8_image_t img_out_opening(src_view.dimensions()); + img_out_opening = erode(src_view,ker_mat,1); + return dilate(view(img_out_opening),ker_mat,1); +} + +template +boost::gil::gray8_image_t closing(SrcView const& src_view, Kernel const& ker_mat) +{ + boost::gil::gray8_image_t img_out_closing(src_view.dimensions()); + img_out_closing = dilate(src_view,ker_mat,1); + return erode(view(img_out_closing),ker_mat,1); +} + + +//This function calculates the difference between pixel values of first image_view and second +//image_view.This function can be used for rgb as well as grayscale images. +template +void difference_impl(SrcView const& src_view, DstView const& dst_view, DiffView const& diff_view) +{ + for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) + for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) + diff_view(view_col, view_row) = src_view(view_col,view_row) - dst_view(view_col,view_row); +} + + +template +void difference(SrcView const& src_view, DstView const& dst_view , DiffView const& diff_view) +{ + + BOOST_ASSERT(src_view.dimensions() == dst_view.dimensions()); + + for (std::size_t i = 0; i < src_view.num_channels(); i++) + { + difference_impl( + nth_channel_view(src_view, i), + nth_channel_view(dst_view, i), + nth_channel_view(diff_view, i) + ); + } +} + +template +boost::gil::gray8_image_t morphological_gradient(SrcView const& src_view, Kernel const& ker_mat) +{ + using namespace boost::gil; + gray8_image_t int_dilate(src_view.dimensions()),int_erode(src_view.dimensions()),res_image(src_view.dimensions()); + int_dilate = dilate(src_view,ker_mat,1); + int_erode = erode(src_view,ker_mat,1); + difference(view(int_dilate),view(int_erode),view(res_image)); + return res_image; +} + +template +boost::gil::gray8_image_t top_hat(SrcView const& src_view, Kernel const& ker_mat) +{ + using namespace boost::gil; + gray8_image_t int_opening(src_view.dimensions()),res_image(src_view.dimensions()); + int_opening = opening(src_view,ker_mat); + difference(src_view,view(int_opening),view(res_image)); + return res_image; +} + +template +boost::gil::gray8_image_t black_hat(SrcView const& src_view, Kernel const& ker_mat) +{ + using namespace boost::gil; + gray8_image_t int_closing(src_view.dimensions()),res_image(src_view.dimensions()); + int_closing = closing(src_view,ker_mat); + difference(view(int_closing), src_view,view(res_image)); + return res_image; +} + +//Summary of applied morphological concepts +//Structuring element is SE = [0.1,0.1,0.1] +// |0.1,0.1,0.1| +// [0.1,0.1,0.1] +//SE(1,1)(center pixel) is the one which coincides with the currently considered pixel of the +//image to be convolved. +//1.Dilation:If 1 or more bright pixels coincide with the structuring element during convolution, +//center pixel is made bright.We can vary the number of times dilation happens by varying the +//argument 'iterations' in the dilate function. +//2.Erosion:If 8 or more bright pixels coincide with the structuring element during convolution, +//center pixel is made bright.We can vary the number of times erosion happens by varying the +//argument 'iterations' in the erode function. +//3.Opening:Opening is just another name of erosion followed by dilation. +//It is useful in removing noise. +//4.Closing:Closing is reverse of Opening, Dilation followed by Erosion. +//It is useful in closing small holes inside the foreground objects, or small black points +//on the object. +//5.Morphological Gradient:It is the difference between dilation and erosion of an image. +//The result will look like the outline of the object. +//6.Top Hat:It is the difference between input image and Opening of the image. +//7.Black Hat:It is the difference between the closing of the input image and input image. + +//Functions have been made for applying above morphological transformations which +//return the transformed image. + +int main() +{ + using namespace boost::gil; + read_image("original.png", img, png_tag{}); + std::vectorker_vec(9,0.1f);//Structuring element + detail::kernel_2d ker_mat(ker_vec.begin(), ker_vec.size(), 1, 1); + gray8_image_t img_out_dilation(img.dimensions()),img_out_erosion(img.dimensions()),img_out_opening(img.dimensions()); + gray8_image_t img_out_closing(img.dimensions()),img_out_mg(img.dimensions()),img_out_top_hat(img.dimensions()); + gray8_image_t img_out_black_hat(img.dimensions()); + //dilate(input_image_view,structuring_element,iterations) + img_out_dilation = dilate(view(img),ker_mat,1); + //erode(input_image_view,structuring_element,iterations) + img_out_erosion = erode(view(img),ker_mat,1); + //opening(input_image_view,structuring_element) + img_out_opening = opening(view(img),ker_mat); + //closing(input_image_view,structuring_element) + img_out_closing = closing(view(img),ker_mat); + //morphological_gradient(input_image_view,structuring_element) + img_out_mg = morphological_gradient(view(img),ker_mat); + //top_hat(input_image_view,structuring_element) + img_out_top_hat = top_hat(view(img),ker_mat); + //black_hat(input_image_view,structuring_element) + img_out_black_hat = black_hat(view(img),ker_mat); + + //Saving results of above morphological transformations. + write_view("out-morphological-example-dilation.png", view(img_out_dilation), png_tag{}); + write_view("out-morphological-example-erosion.png", view(img_out_erosion), png_tag{}); + write_view("out-morphological-example-opening.png", view(img_out_opening), png_tag{}); + write_view("out-morphological-example-closing.png", view(img_out_closing), png_tag{}); + write_view("out-morphological-example-morphological_gradient.png", view(img_out_mg), png_tag{}); + write_view("out-morphological-example-top_hat.png", view(img_out_top_hat), png_tag{}); + write_view("out-morphological-example-black_hat.png", view(img_out_black_hat), png_tag{}); +} diff --git a/example/original.png b/example/original.png new file mode 100644 index 0000000000000000000000000000000000000000..b63e99ed9da7b769fd4fe45826f1f5118fb24297 GIT binary patch literal 2082 zcmZ8iZB!Fi8U~6e6lgL-Es3HqNe0s5Za%OUTm@l-02eGGm}5C53=p(+p&(Y24~YWK zK(s~zJ5gHBi8NB>s42CDEv14Z@)2P@Srsd~k^)M*T0KZn5ZybR-Tv4gbMJkhdGEdN zecmtn{lpkA521&Xlap7hir5V2d+@7Y0tY9@y4#~pPKzgFi49wdobPnWkNh0%QaSqS zjxOi@^TQ>-X)lhwvGd>?_lTT(es>3(tFzub(NvAy zIzL_N=%N<~u4pLwB>>1_qlr^ZWhdM<)3v6ru8s!PTca3@j-!I7^6GIpP-Cc@kD( zks#cOtGc|>&2*QNl z-@N~ND`WIcdN{QDW0^FG2q~KzompwR+{E4haX$RR>1DIiIl0YWB(C z_K7Nv)~o{Z13a*r3WW%+5Lo54{A?l}lG1*4jQtiQ8u_K%O}9bf&VeyPaBVBRWQ}Qs zRcaUYQyZ?^ztSFH-i`lH+1sWat0O6k$XzgUB>fM9Ywvt#c=&Nxe;Q zW`6;35cEMMAkh`){i+D%Gf-Lt5(%7#o<5a)H5d=XP>OUcwFe3z| z#s^FUXoj)3*|Mn+_*c{U+VTgCs-?@5=ZDgyW1TXt3HUFSpCtNS%?;aAHk~@2XY(~E zb?Rr~%I3JEtJ`P@dCAD=2_RC*sNSX!^z0zGmYLX2K*BgpbTszJ5|9vZQ2JO3I_5mA9KC5A zgw#;RNyoMLQ;NB zuIpv0R2`-J=4=?w6WDnJ^bvQWhrlk(&5n0-5K6yE)k7$R{kyFWDywzyWnvKDGT;jB zA{Uvnq2IQV|9mw4yu10A$t}u@1SflOIQ&177yja<=p+}nuK}^pB1sJhvjm(4G2q$w zsr3EYEf>OXddj@=v%^R~EF+qha?~~oB&pbDZN+efAm9dEFvC>>JXNI7Qp42(?1rdd zVx84*>I=1@ZT9A?m-CCaS~l(MdrGgS&xF5vazET1ruZ=TN?jkdn?AFDekOeXKVV0F u^w54g2gVt>+wmdSAYM%We=~M;&9AKA^Y#TxX!BmK`NwWdB+f=^4*UmVeU2^w literal 0 HcmV?d00001 From 48436fc82ab3d6ffbd2ce13d343640edc54ad02b Mon Sep 17 00:00:00 2001 From: meshtag Date: Thu, 14 Jan 2021 21:49:53 +0530 Subject: [PATCH 02/14] Improved comments and some other things --- example/morphology.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/example/morphology.cpp b/example/morphology.cpp index 27acd6d795..be27ee52d4 100644 --- a/example/morphology.cpp +++ b/example/morphology.cpp @@ -5,9 +5,8 @@ #include #include -boost::gil::gray8_image_t img; -//This function is used for applying basic threshold and convolution operations which are applied +//This function is used for applying basic thresholding and convolution operations which are applied //under the hood for all morphological transformations. template boost::gil::gray8_image_t thresh_con_thresh(SrcView const& src_view, Kernel const& ker_mat,const int threshold1,const int threshold2) @@ -20,26 +19,34 @@ boost::gil::gray8_image_t thresh_con_thresh(SrcView const& src_view, Kernel cons return intermediate_img; } +// Dilation:If 1 or more bright pixels coincide with the structuring element during convolution, +// center pixel is made bright.We can vary the number of times dilation happens by varying the +// argument 'iterations' in the dilate function. template boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat,const int iterations) { boost::gil::gray8_image_t img_out_dilation(src_view.dimensions()); - img_out_dilation = img; + boost::gil::transform_pixels(src_view,view(img_out_dilation),[](const boost::gil::gray8_pixel_t& p){return p[0];}); for(int i=0;i boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,const int iterations) { boost::gil::gray8_image_t img_out_erosion(src_view.dimensions()); - img_out_erosion = img; + boost::gil::transform_pixels(src_view,view(img_out_erosion),[](const boost::gil::gray8_pixel_t& p){return p[0];}); for(int i=0;i boost::gil::gray8_image_t opening(SrcView const& src_view, Kernel const& ker_mat) { @@ -48,6 +55,9 @@ boost::gil::gray8_image_t opening(SrcView const& src_view, Kernel const& ker_mat return dilate(view(img_out_opening),ker_mat,1); } +//Closing:Closing is reverse of Opening, Dilation followed by Erosion. +//It is useful in closing small holes inside the foreground objects, or small black points +//on the object. template boost::gil::gray8_image_t closing(SrcView const& src_view, Kernel const& ker_mat) { @@ -84,6 +94,8 @@ void difference(SrcView const& src_view, DstView const& dst_view , DiffView cons } } +//Morphological Gradient:It is the difference between dilation and erosion of an image. +//The result will look like the outline of the object. template boost::gil::gray8_image_t morphological_gradient(SrcView const& src_view, Kernel const& ker_mat) { @@ -95,6 +107,7 @@ boost::gil::gray8_image_t morphological_gradient(SrcView const& src_view, Kernel return res_image; } +//Top Hat:It is the difference between input image and Opening of the image. template boost::gil::gray8_image_t top_hat(SrcView const& src_view, Kernel const& ker_mat) { @@ -105,6 +118,7 @@ boost::gil::gray8_image_t top_hat(SrcView const& src_view, Kernel const& ker_mat return res_image; } +//Black Hat:It is the difference between the closing of the input image and input image. template boost::gil::gray8_image_t black_hat(SrcView const& src_view, Kernel const& ker_mat) { @@ -115,34 +129,16 @@ boost::gil::gray8_image_t black_hat(SrcView const& src_view, Kernel const& ker_m return res_image; } -//Summary of applied morphological concepts //Structuring element is SE = [0.1,0.1,0.1] // |0.1,0.1,0.1| // [0.1,0.1,0.1] //SE(1,1)(center pixel) is the one which coincides with the currently considered pixel of the //image to be convolved. -//1.Dilation:If 1 or more bright pixels coincide with the structuring element during convolution, -//center pixel is made bright.We can vary the number of times dilation happens by varying the -//argument 'iterations' in the dilate function. -//2.Erosion:If 8 or more bright pixels coincide with the structuring element during convolution, -//center pixel is made bright.We can vary the number of times erosion happens by varying the -//argument 'iterations' in the erode function. -//3.Opening:Opening is just another name of erosion followed by dilation. -//It is useful in removing noise. -//4.Closing:Closing is reverse of Opening, Dilation followed by Erosion. -//It is useful in closing small holes inside the foreground objects, or small black points -//on the object. -//5.Morphological Gradient:It is the difference between dilation and erosion of an image. -//The result will look like the outline of the object. -//6.Top Hat:It is the difference between input image and Opening of the image. -//7.Black Hat:It is the difference between the closing of the input image and input image. - -//Functions have been made for applying above morphological transformations which -//return the transformed image. int main() { using namespace boost::gil; + boost::gil::gray8_image_t img; read_image("original.png", img, png_tag{}); std::vectorker_vec(9,0.1f);//Structuring element detail::kernel_2d ker_mat(ker_vec.begin(), ker_vec.size(), 1, 1); From 14900be7116e0002090569a637d4d52928bc0cea Mon Sep 17 00:00:00 2001 From: meshtag Date: Sun, 17 Jan 2021 12:58:55 +0530 Subject: [PATCH 03/14] Applied adviced changes --- example/morphology.cpp | 135 +----------------- .../boost/gil/image_processing/morphology.hpp | 131 +++++++++++++++++ 2 files changed, 135 insertions(+), 131 deletions(-) create mode 100644 include/boost/gil/image_processing/morphology.hpp diff --git a/example/morphology.cpp b/example/morphology.cpp index be27ee52d4..15c4d158a9 100644 --- a/example/morphology.cpp +++ b/example/morphology.cpp @@ -1,137 +1,10 @@ -#include -#include #include +#include #include -#include -#include - -//This function is used for applying basic thresholding and convolution operations which are applied -//under the hood for all morphological transformations. -template -boost::gil::gray8_image_t thresh_con_thresh(SrcView const& src_view, Kernel const& ker_mat,const int threshold1,const int threshold2) -{ - using namespace boost::gil; - boost::gil::gray8_image_t intermediate_img(src_view.dimensions()); - threshold_binary(src_view, view(intermediate_img),threshold1, 255); - detail::convolve_2d(view(intermediate_img), ker_mat, view(intermediate_img)); - threshold_binary(const_view(intermediate_img),view(intermediate_img),threshold2,255); - return intermediate_img; -} - -// Dilation:If 1 or more bright pixels coincide with the structuring element during convolution, -// center pixel is made bright.We can vary the number of times dilation happens by varying the -// argument 'iterations' in the dilate function. -template -boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat,const int iterations) -{ - boost::gil::gray8_image_t img_out_dilation(src_view.dimensions()); - boost::gil::transform_pixels(src_view,view(img_out_dilation),[](const boost::gil::gray8_pixel_t& p){return p[0];}); - for(int i=0;i -boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,const int iterations) -{ - boost::gil::gray8_image_t img_out_erosion(src_view.dimensions()); - boost::gil::transform_pixels(src_view,view(img_out_erosion),[](const boost::gil::gray8_pixel_t& p){return p[0];}); - for(int i=0;i -boost::gil::gray8_image_t opening(SrcView const& src_view, Kernel const& ker_mat) -{ - boost::gil::gray8_image_t img_out_opening(src_view.dimensions()); - img_out_opening = erode(src_view,ker_mat,1); - return dilate(view(img_out_opening),ker_mat,1); -} - -//Closing:Closing is reverse of Opening, Dilation followed by Erosion. -//It is useful in closing small holes inside the foreground objects, or small black points -//on the object. -template -boost::gil::gray8_image_t closing(SrcView const& src_view, Kernel const& ker_mat) -{ - boost::gil::gray8_image_t img_out_closing(src_view.dimensions()); - img_out_closing = dilate(src_view,ker_mat,1); - return erode(view(img_out_closing),ker_mat,1); -} - - -//This function calculates the difference between pixel values of first image_view and second -//image_view.This function can be used for rgb as well as grayscale images. -template -void difference_impl(SrcView const& src_view, DstView const& dst_view, DiffView const& diff_view) -{ - for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) - for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) - diff_view(view_col, view_row) = src_view(view_col,view_row) - dst_view(view_col,view_row); -} - - -template -void difference(SrcView const& src_view, DstView const& dst_view , DiffView const& diff_view) -{ - - BOOST_ASSERT(src_view.dimensions() == dst_view.dimensions()); - - for (std::size_t i = 0; i < src_view.num_channels(); i++) - { - difference_impl( - nth_channel_view(src_view, i), - nth_channel_view(dst_view, i), - nth_channel_view(diff_view, i) - ); - } -} - -//Morphological Gradient:It is the difference between dilation and erosion of an image. -//The result will look like the outline of the object. -template -boost::gil::gray8_image_t morphological_gradient(SrcView const& src_view, Kernel const& ker_mat) -{ - using namespace boost::gil; - gray8_image_t int_dilate(src_view.dimensions()),int_erode(src_view.dimensions()),res_image(src_view.dimensions()); - int_dilate = dilate(src_view,ker_mat,1); - int_erode = erode(src_view,ker_mat,1); - difference(view(int_dilate),view(int_erode),view(res_image)); - return res_image; -} - -//Top Hat:It is the difference between input image and Opening of the image. -template -boost::gil::gray8_image_t top_hat(SrcView const& src_view, Kernel const& ker_mat) -{ - using namespace boost::gil; - gray8_image_t int_opening(src_view.dimensions()),res_image(src_view.dimensions()); - int_opening = opening(src_view,ker_mat); - difference(src_view,view(int_opening),view(res_image)); - return res_image; -} - -//Black Hat:It is the difference between the closing of the input image and input image. -template -boost::gil::gray8_image_t black_hat(SrcView const& src_view, Kernel const& ker_mat) -{ - using namespace boost::gil; - gray8_image_t int_closing(src_view.dimensions()),res_image(src_view.dimensions()); - int_closing = closing(src_view,ker_mat); - difference(view(int_closing), src_view,view(res_image)); - return res_image; -} - -//Structuring element is SE = [0.1,0.1,0.1] -// |0.1,0.1,0.1| -// [0.1,0.1,0.1] +//current structuring element is SE = [0.1,0.1,0.1] +// |0.1,0.1,0.1| +// [0.1,0.1,0.1] //SE(1,1)(center pixel) is the one which coincides with the currently considered pixel of the //image to be convolved. diff --git a/include/boost/gil/image_processing/morphology.hpp b/include/boost/gil/image_processing/morphology.hpp new file mode 100644 index 0000000000..ee29f9f8d0 --- /dev/null +++ b/include/boost/gil/image_processing/morphology.hpp @@ -0,0 +1,131 @@ +#ifndef BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP +#define BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP + +#include +#include +#include + + +//This function is used for applying basic thresholding and convolution operations which are applied +//under the hood for all morphological transformations. +template +boost::gil::gray8_image_t thresh_con_thresh(SrcView const& src_view, Kernel const& ker_mat,const int threshold1,const int threshold2) +{ + using namespace boost::gil; + boost::gil::gray8_image_t intermediate_img(src_view.dimensions()); + threshold_binary(src_view, view(intermediate_img),threshold1, 255); + detail::convolve_2d(view(intermediate_img), ker_mat, view(intermediate_img)); + threshold_binary(const_view(intermediate_img),view(intermediate_img),threshold2,255); + return intermediate_img; +} + +// Dilation:If 1 or more bright pixels coincide with the structuring element during convolution, +// center pixel is made bright.We can vary the number of times dilation happens by varying the +// argument 'iterations' in the dilate function. +template +boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat,const int iterations) +{ + boost::gil::gray8_image_t img_out_dilation(src_view.dimensions()); + boost::gil::transform_pixels(src_view,view(img_out_dilation),[](const boost::gil::gray8_pixel_t& p){return p[0];}); + for(int i=0;i +boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,const int iterations) +{ + boost::gil::gray8_image_t img_out_erosion(src_view.dimensions()); + boost::gil::transform_pixels(src_view,view(img_out_erosion),[](const boost::gil::gray8_pixel_t& p){return p[0];}); + for(int i=0;i +boost::gil::gray8_image_t opening(SrcView const& src_view, Kernel const& ker_mat) +{ + boost::gil::gray8_image_t img_out_opening(src_view.dimensions()); + img_out_opening = erode(src_view,ker_mat,1); + return dilate(view(img_out_opening),ker_mat,1); +} + +//Closing:Closing is reverse of Opening, Dilation followed by Erosion. +//It is useful in closing small holes inside the foreground objects, or small black points +//on the object. +template +boost::gil::gray8_image_t closing(SrcView const& src_view, Kernel const& ker_mat) +{ + boost::gil::gray8_image_t img_out_closing(src_view.dimensions()); + img_out_closing = dilate(src_view,ker_mat,1); + return erode(view(img_out_closing),ker_mat,1); +} + + +//This function calculates the difference between pixel values of first image_view and second +//image_view.This function can be used for rgb as well as grayscale images. +template +void difference_impl(SrcView const& src_view, DstView const& dst_view, DiffView const& diff_view) +{ + for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) + for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) + diff_view(view_col, view_row) = src_view(view_col,view_row) - dst_view(view_col,view_row); +} + + +template +void difference(SrcView const& src_view, DstView const& dst_view , DiffView const& diff_view) +{ + + BOOST_ASSERT(src_view.dimensions() == dst_view.dimensions()); + + for (std::size_t i = 0; i < src_view.num_channels(); i++) + { + difference_impl( + nth_channel_view(src_view, i), + nth_channel_view(dst_view, i), + nth_channel_view(diff_view, i) + ); + } +} + +//Morphological Gradient:It is the difference between dilation and erosion of an image. +//The result will look like the outline of the object. +template +boost::gil::gray8_image_t morphological_gradient(SrcView const& src_view, Kernel const& ker_mat) +{ + using namespace boost::gil; + gray8_image_t int_dilate(src_view.dimensions()),int_erode(src_view.dimensions()),res_image(src_view.dimensions()); + int_dilate = dilate(src_view,ker_mat,1); + int_erode = erode(src_view,ker_mat,1); + difference(view(int_dilate),view(int_erode),view(res_image)); + return res_image; +} + +//Top Hat:It is the difference between input image and Opening of the image. +template +boost::gil::gray8_image_t top_hat(SrcView const& src_view, Kernel const& ker_mat) +{ + using namespace boost::gil; + gray8_image_t int_opening(src_view.dimensions()),res_image(src_view.dimensions()); + int_opening = opening(src_view,ker_mat); + difference(src_view,view(int_opening),view(res_image)); + return res_image; +} + +//Black Hat:It is the difference between the closing of the input image and input image. +template +boost::gil::gray8_image_t black_hat(SrcView const& src_view, Kernel const& ker_mat) +{ + using namespace boost::gil; + gray8_image_t int_closing(src_view.dimensions()),res_image(src_view.dimensions()); + int_closing = closing(src_view,ker_mat); + difference(view(int_closing), src_view,view(res_image)); + return res_image; +} +#endif //BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP \ No newline at end of file From 53d92b28451757a05a5043cdac1e9e96b13b3740 Mon Sep 17 00:00:00 2001 From: meshtag Date: Sun, 17 Jan 2021 13:00:00 +0530 Subject: [PATCH 04/14] Applied adviced changes --- example/morphology.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/morphology.cpp b/example/morphology.cpp index 15c4d158a9..304e409147 100644 --- a/example/morphology.cpp +++ b/example/morphology.cpp @@ -6,7 +6,7 @@ // |0.1,0.1,0.1| // [0.1,0.1,0.1] //SE(1,1)(center pixel) is the one which coincides with the currently considered pixel of the -//image to be convolved. +//image to be convolved. The structuring element can be easily changed by the user. int main() { From 6ac3102cec60370f6e7ce590bacf0d1a591f3010 Mon Sep 17 00:00:00 2001 From: meshtag Date: Wed, 20 Jan 2021 17:05:51 +0530 Subject: [PATCH 05/14] Should handle grayscale dilation/erosion --- example/morphology.cpp | 14 ++-- .../boost/gil/image_processing/morphology.hpp | 70 +++++++++++++++---- 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/example/morphology.cpp b/example/morphology.cpp index 304e409147..dcd0a17030 100644 --- a/example/morphology.cpp +++ b/example/morphology.cpp @@ -2,9 +2,9 @@ #include #include -//current structuring element is SE = [0.1,0.1,0.1] -// |0.1,0.1,0.1| -// [0.1,0.1,0.1] +//Default structuring element is SE = [1,1,1] +// |1,1,1| +// [1,1,1] //SE(1,1)(center pixel) is the one which coincides with the currently considered pixel of the //image to be convolved. The structuring element can be easily changed by the user. @@ -13,7 +13,13 @@ int main() using namespace boost::gil; boost::gil::gray8_image_t img; read_image("original.png", img, png_tag{}); - std::vectorker_vec(9,0.1f);//Structuring element + + //Image can be converted to a binary format with high value as 255 and low value as 0 + //by uncommenting the following threshold operator.This can be used for binary morphological + //operations. + threshold_binary(view(img), view(img),170, 255); + + std::vectorker_vec(9,1.0f);//Structuring element detail::kernel_2d ker_mat(ker_vec.begin(), ker_vec.size(), 1, 1); gray8_image_t img_out_dilation(img.dimensions()),img_out_erosion(img.dimensions()),img_out_opening(img.dimensions()); gray8_image_t img_out_closing(img.dimensions()),img_out_mg(img.dimensions()),img_out_top_hat(img.dimensions()); diff --git a/include/boost/gil/image_processing/morphology.hpp b/include/boost/gil/image_processing/morphology.hpp index ee29f9f8d0..2bd1c20c2e 100644 --- a/include/boost/gil/image_processing/morphology.hpp +++ b/include/boost/gil/image_processing/morphology.hpp @@ -1,26 +1,68 @@ #ifndef BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP #define BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP -#include #include -#include +template +void morph_impl(SrcView const& src_view, DstView const& dst_view, Kernel const& kernel,const int identifier) +{ + int flip_ker_row, flip_ker_col, row_boundary, col_boundary; + int max_overlapped_element,min_overlapped_element; + for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) + { + for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) + { + max_overlapped_element = 0,min_overlapped_element = 256; + for (std::size_t kernel_row = 0; kernel_row < kernel.size(); ++kernel_row) + { + flip_ker_row = kernel.size() - 1 - kernel_row; // row index of flipped kernel + + for (std::size_t kernel_col = 0; kernel_col < kernel.size(); ++kernel_col) + { + flip_ker_col = kernel.size() - 1 - kernel_col; // column index of flipped kernel + + // index of input signal, used for checking boundary + row_boundary = view_row + (kernel.center_y() - flip_ker_row); + col_boundary = view_col + (kernel.center_x() - flip_ker_col); + + // ignore input samples which are out of bound + if (row_boundary >= 0 && row_boundary < src_view.height() && + col_boundary >= 0 && col_boundary < src_view.width()) + { + if(src_view(col_boundary, row_boundary) > max_overlapped_element) + max_overlapped_element = src_view(col_boundary, row_boundary); + if(src_view(col_boundary, row_boundary) < min_overlapped_element) + min_overlapped_element = src_view(col_boundary, row_boundary); + } + } + } + if(identifier)//identifier = 1 for dilation + dst_view(view_col, view_row) = max_overlapped_element; + else //identifier = 0 for erosion + dst_view(view_col, view_row) = min_overlapped_element; + } + } +} -//This function is used for applying basic thresholding and convolution operations which are applied -//under the hood for all morphological transformations. template -boost::gil::gray8_image_t thresh_con_thresh(SrcView const& src_view, Kernel const& ker_mat,const int threshold1,const int threshold2) +boost::gil::gray8_image_t morph(SrcView const& src_view, Kernel const& ker_mat,const int identifier) { using namespace boost::gil; + BOOST_ASSERT(ker_mat.size() != 0); boost::gil::gray8_image_t intermediate_img(src_view.dimensions()); - threshold_binary(src_view, view(intermediate_img),threshold1, 255); - detail::convolve_2d(view(intermediate_img), ker_mat, view(intermediate_img)); - threshold_binary(const_view(intermediate_img),view(intermediate_img),threshold2,255); + for (std::size_t i = 0; i < src_view.num_channels(); i++) + { + morph_impl( + nth_channel_view(src_view, i), + nth_channel_view(view(intermediate_img), i), + ker_mat,identifier + ); + } return intermediate_img; } -// Dilation:If 1 or more bright pixels coincide with the structuring element during convolution, -// center pixel is made bright.We can vary the number of times dilation happens by varying the +// Dilation:Give the maximum overlapped value to the pixel overlapping with the center element of +//structuring element.We can vary the number of times dilation happens by varying the // argument 'iterations' in the dilate function. template boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat,const int iterations) @@ -28,12 +70,12 @@ boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat, boost::gil::gray8_image_t img_out_dilation(src_view.dimensions()); boost::gil::transform_pixels(src_view,view(img_out_dilation),[](const boost::gil::gray8_pixel_t& p){return p[0];}); for(int i=0;i boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,const int iterations) @@ -41,7 +83,7 @@ boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,c boost::gil::gray8_image_t img_out_erosion(src_view.dimensions()); boost::gil::transform_pixels(src_view,view(img_out_erosion),[](const boost::gil::gray8_pixel_t& p){return p[0];}); for(int i=0;i Date: Fri, 22 Jan 2021 00:58:18 +0530 Subject: [PATCH 06/14] Checking --- example/morphology.cpp | 50 ----- example/original.png | Bin 2082 -> 0 bytes .../boost/gil/image_processing/morphology.hpp | 173 ------------------ 3 files changed, 223 deletions(-) delete mode 100644 example/morphology.cpp delete mode 100644 example/original.png delete mode 100644 include/boost/gil/image_processing/morphology.hpp diff --git a/example/morphology.cpp b/example/morphology.cpp deleted file mode 100644 index dcd0a17030..0000000000 --- a/example/morphology.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include - -//Default structuring element is SE = [1,1,1] -// |1,1,1| -// [1,1,1] -//SE(1,1)(center pixel) is the one which coincides with the currently considered pixel of the -//image to be convolved. The structuring element can be easily changed by the user. - -int main() -{ - using namespace boost::gil; - boost::gil::gray8_image_t img; - read_image("original.png", img, png_tag{}); - - //Image can be converted to a binary format with high value as 255 and low value as 0 - //by uncommenting the following threshold operator.This can be used for binary morphological - //operations. - threshold_binary(view(img), view(img),170, 255); - - std::vectorker_vec(9,1.0f);//Structuring element - detail::kernel_2d ker_mat(ker_vec.begin(), ker_vec.size(), 1, 1); - gray8_image_t img_out_dilation(img.dimensions()),img_out_erosion(img.dimensions()),img_out_opening(img.dimensions()); - gray8_image_t img_out_closing(img.dimensions()),img_out_mg(img.dimensions()),img_out_top_hat(img.dimensions()); - gray8_image_t img_out_black_hat(img.dimensions()); - //dilate(input_image_view,structuring_element,iterations) - img_out_dilation = dilate(view(img),ker_mat,1); - //erode(input_image_view,structuring_element,iterations) - img_out_erosion = erode(view(img),ker_mat,1); - //opening(input_image_view,structuring_element) - img_out_opening = opening(view(img),ker_mat); - //closing(input_image_view,structuring_element) - img_out_closing = closing(view(img),ker_mat); - //morphological_gradient(input_image_view,structuring_element) - img_out_mg = morphological_gradient(view(img),ker_mat); - //top_hat(input_image_view,structuring_element) - img_out_top_hat = top_hat(view(img),ker_mat); - //black_hat(input_image_view,structuring_element) - img_out_black_hat = black_hat(view(img),ker_mat); - - //Saving results of above morphological transformations. - write_view("out-morphological-example-dilation.png", view(img_out_dilation), png_tag{}); - write_view("out-morphological-example-erosion.png", view(img_out_erosion), png_tag{}); - write_view("out-morphological-example-opening.png", view(img_out_opening), png_tag{}); - write_view("out-morphological-example-closing.png", view(img_out_closing), png_tag{}); - write_view("out-morphological-example-morphological_gradient.png", view(img_out_mg), png_tag{}); - write_view("out-morphological-example-top_hat.png", view(img_out_top_hat), png_tag{}); - write_view("out-morphological-example-black_hat.png", view(img_out_black_hat), png_tag{}); -} diff --git a/example/original.png b/example/original.png deleted file mode 100644 index b63e99ed9da7b769fd4fe45826f1f5118fb24297..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2082 zcmZ8iZB!Fi8U~6e6lgL-Es3HqNe0s5Za%OUTm@l-02eGGm}5C53=p(+p&(Y24~YWK zK(s~zJ5gHBi8NB>s42CDEv14Z@)2P@Srsd~k^)M*T0KZn5ZybR-Tv4gbMJkhdGEdN zecmtn{lpkA521&Xlap7hir5V2d+@7Y0tY9@y4#~pPKzgFi49wdobPnWkNh0%QaSqS zjxOi@^TQ>-X)lhwvGd>?_lTT(es>3(tFzub(NvAy zIzL_N=%N<~u4pLwB>>1_qlr^ZWhdM<)3v6ru8s!PTca3@j-!I7^6GIpP-Cc@kD( zks#cOtGc|>&2*QNl z-@N~ND`WIcdN{QDW0^FG2q~KzompwR+{E4haX$RR>1DIiIl0YWB(C z_K7Nv)~o{Z13a*r3WW%+5Lo54{A?l}lG1*4jQtiQ8u_K%O}9bf&VeyPaBVBRWQ}Qs zRcaUYQyZ?^ztSFH-i`lH+1sWat0O6k$XzgUB>fM9Ywvt#c=&Nxe;Q zW`6;35cEMMAkh`){i+D%Gf-Lt5(%7#o<5a)H5d=XP>OUcwFe3z| z#s^FUXoj)3*|Mn+_*c{U+VTgCs-?@5=ZDgyW1TXt3HUFSpCtNS%?;aAHk~@2XY(~E zb?Rr~%I3JEtJ`P@dCAD=2_RC*sNSX!^z0zGmYLX2K*BgpbTszJ5|9vZQ2JO3I_5mA9KC5A zgw#;RNyoMLQ;NB zuIpv0R2`-J=4=?w6WDnJ^bvQWhrlk(&5n0-5K6yE)k7$R{kyFWDywzyWnvKDGT;jB zA{Uvnq2IQV|9mw4yu10A$t}u@1SflOIQ&177yja<=p+}nuK}^pB1sJhvjm(4G2q$w zsr3EYEf>OXddj@=v%^R~EF+qha?~~oB&pbDZN+efAm9dEFvC>>JXNI7Qp42(?1rdd zVx84*>I=1@ZT9A?m-CCaS~l(MdrGgS&xF5vazET1ruZ=TN?jkdn?AFDekOeXKVV0F u^w54g2gVt>+wmdSAYM%We=~M;&9AKA^Y#TxX!BmK`NwWdB+f=^4*UmVeU2^w diff --git a/include/boost/gil/image_processing/morphology.hpp b/include/boost/gil/image_processing/morphology.hpp deleted file mode 100644 index 2bd1c20c2e..0000000000 --- a/include/boost/gil/image_processing/morphology.hpp +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP -#define BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP - -#include - -template -void morph_impl(SrcView const& src_view, DstView const& dst_view, Kernel const& kernel,const int identifier) -{ - int flip_ker_row, flip_ker_col, row_boundary, col_boundary; - int max_overlapped_element,min_overlapped_element; - for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) - { - for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) - { - max_overlapped_element = 0,min_overlapped_element = 256; - for (std::size_t kernel_row = 0; kernel_row < kernel.size(); ++kernel_row) - { - flip_ker_row = kernel.size() - 1 - kernel_row; // row index of flipped kernel - - for (std::size_t kernel_col = 0; kernel_col < kernel.size(); ++kernel_col) - { - flip_ker_col = kernel.size() - 1 - kernel_col; // column index of flipped kernel - - // index of input signal, used for checking boundary - row_boundary = view_row + (kernel.center_y() - flip_ker_row); - col_boundary = view_col + (kernel.center_x() - flip_ker_col); - - // ignore input samples which are out of bound - if (row_boundary >= 0 && row_boundary < src_view.height() && - col_boundary >= 0 && col_boundary < src_view.width()) - { - if(src_view(col_boundary, row_boundary) > max_overlapped_element) - max_overlapped_element = src_view(col_boundary, row_boundary); - if(src_view(col_boundary, row_boundary) < min_overlapped_element) - min_overlapped_element = src_view(col_boundary, row_boundary); - } - } - } - if(identifier)//identifier = 1 for dilation - dst_view(view_col, view_row) = max_overlapped_element; - else //identifier = 0 for erosion - dst_view(view_col, view_row) = min_overlapped_element; - } - } -} - -template -boost::gil::gray8_image_t morph(SrcView const& src_view, Kernel const& ker_mat,const int identifier) -{ - using namespace boost::gil; - BOOST_ASSERT(ker_mat.size() != 0); - boost::gil::gray8_image_t intermediate_img(src_view.dimensions()); - for (std::size_t i = 0; i < src_view.num_channels(); i++) - { - morph_impl( - nth_channel_view(src_view, i), - nth_channel_view(view(intermediate_img), i), - ker_mat,identifier - ); - } - return intermediate_img; -} - -// Dilation:Give the maximum overlapped value to the pixel overlapping with the center element of -//structuring element.We can vary the number of times dilation happens by varying the -// argument 'iterations' in the dilate function. -template -boost::gil::gray8_image_t dilate(SrcView const& src_view, Kernel const& ker_mat,const int iterations) -{ - boost::gil::gray8_image_t img_out_dilation(src_view.dimensions()); - boost::gil::transform_pixels(src_view,view(img_out_dilation),[](const boost::gil::gray8_pixel_t& p){return p[0];}); - for(int i=0;i -boost::gil::gray8_image_t erode(SrcView const& src_view, Kernel const& ker_mat,const int iterations) -{ - boost::gil::gray8_image_t img_out_erosion(src_view.dimensions()); - boost::gil::transform_pixels(src_view,view(img_out_erosion),[](const boost::gil::gray8_pixel_t& p){return p[0];}); - for(int i=0;i -boost::gil::gray8_image_t opening(SrcView const& src_view, Kernel const& ker_mat) -{ - boost::gil::gray8_image_t img_out_opening(src_view.dimensions()); - img_out_opening = erode(src_view,ker_mat,1); - return dilate(view(img_out_opening),ker_mat,1); -} - -//Closing:Closing is reverse of Opening, Dilation followed by Erosion. -//It is useful in closing small holes inside the foreground objects, or small black points -//on the object. -template -boost::gil::gray8_image_t closing(SrcView const& src_view, Kernel const& ker_mat) -{ - boost::gil::gray8_image_t img_out_closing(src_view.dimensions()); - img_out_closing = dilate(src_view,ker_mat,1); - return erode(view(img_out_closing),ker_mat,1); -} - - -//This function calculates the difference between pixel values of first image_view and second -//image_view.This function can be used for rgb as well as grayscale images. -template -void difference_impl(SrcView const& src_view, DstView const& dst_view, DiffView const& diff_view) -{ - for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) - for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) - diff_view(view_col, view_row) = src_view(view_col,view_row) - dst_view(view_col,view_row); -} - - -template -void difference(SrcView const& src_view, DstView const& dst_view , DiffView const& diff_view) -{ - - BOOST_ASSERT(src_view.dimensions() == dst_view.dimensions()); - - for (std::size_t i = 0; i < src_view.num_channels(); i++) - { - difference_impl( - nth_channel_view(src_view, i), - nth_channel_view(dst_view, i), - nth_channel_view(diff_view, i) - ); - } -} - -//Morphological Gradient:It is the difference between dilation and erosion of an image. -//The result will look like the outline of the object. -template -boost::gil::gray8_image_t morphological_gradient(SrcView const& src_view, Kernel const& ker_mat) -{ - using namespace boost::gil; - gray8_image_t int_dilate(src_view.dimensions()),int_erode(src_view.dimensions()),res_image(src_view.dimensions()); - int_dilate = dilate(src_view,ker_mat,1); - int_erode = erode(src_view,ker_mat,1); - difference(view(int_dilate),view(int_erode),view(res_image)); - return res_image; -} - -//Top Hat:It is the difference between input image and Opening of the image. -template -boost::gil::gray8_image_t top_hat(SrcView const& src_view, Kernel const& ker_mat) -{ - using namespace boost::gil; - gray8_image_t int_opening(src_view.dimensions()),res_image(src_view.dimensions()); - int_opening = opening(src_view,ker_mat); - difference(src_view,view(int_opening),view(res_image)); - return res_image; -} - -//Black Hat:It is the difference between the closing of the input image and input image. -template -boost::gil::gray8_image_t black_hat(SrcView const& src_view, Kernel const& ker_mat) -{ - using namespace boost::gil; - gray8_image_t int_closing(src_view.dimensions()),res_image(src_view.dimensions()); - int_closing = closing(src_view,ker_mat); - difference(view(int_closing), src_view,view(res_image)); - return res_image; -} -#endif //BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP \ No newline at end of file From d7a3e8859dbb99da4083bd914dd1e2482772eea5 Mon Sep 17 00:00:00 2001 From: meshtag Date: Fri, 12 Mar 2021 21:14:22 +0530 Subject: [PATCH 07/14] Port TuttleOFX pattern extension Add shrink First checkpoint test cases added Add pattern Updates Updates Port TuttleOFX extensions Improve comments Update copyright Improve copyright header Pass build Port pattern Improved comment --- .../gil/extension/toolbox/metafunctions.hpp | 1 + .../toolbox/metafunctions/pattern.hpp | 63 +++++ test/extension/toolbox/CMakeLists.txt | 3 +- test/extension/toolbox/Jamfile | 1 + test/extension/toolbox/pattern.cpp | 237 ++++++++++++++++++ 5 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 include/boost/gil/extension/toolbox/metafunctions/pattern.hpp create mode 100644 test/extension/toolbox/pattern.cpp diff --git a/include/boost/gil/extension/toolbox/metafunctions.hpp b/include/boost/gil/extension/toolbox/metafunctions.hpp index 16d7ee0184..21457b5fdf 100644 --- a/include/boost/gil/extension/toolbox/metafunctions.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions.hpp @@ -16,5 +16,6 @@ #include #include #include +#include #endif diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp new file mode 100644 index 0000000000..b18ef1c3d3 --- /dev/null +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -0,0 +1,63 @@ +// Copyright Tom Brinkman 2008. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef _pattern_hpp_ +#define _pattern_hpp_ + +#include + +namespace boost { namespace gil { + +/// \brief Repeatedly copies smaller image view passed through the struct constructor in subimage +/// views of the larger image view passed through overloaded '()' operator. +template +struct pattern +{ + view_t v2; + pattern(view_t v2) + : v2(v2) + { + } + + void operator()(view_t& view) + { + using namespace boost::gil; + + int h = v2.height(); + int w = v2.width(); + + // For ensuring that view passed through '()' operator has larger dimensions than view + // passed through the constructor. + if(h > view.height() || w > view.width()) + return; + + int n = 0; + for(int x = 0; x < view.width(); x += w) + { + for(int y = 0; y < view.height(); y += h) + { + int aw = w; + if(x + w > view.width()) + { + int t = x + w - view.width(); + aw = w - t; + } + + int ah = h; + if(y + h > view.height()) + { + int t = y + h - view.height(); + ah = h - t; + } + + view_t v3 = subimage_view(view, x, y, aw, ah); + view_t v4 = subimage_view(v2, 0, 0, aw, ah); + boost::gil::copy_pixels(v4, v3); + } + } + } +}; +} } + +#endif diff --git a/test/extension/toolbox/CMakeLists.txt b/test/extension/toolbox/CMakeLists.txt index 70df68db42..ff1d08b6c4 100644 --- a/test/extension/toolbox/CMakeLists.txt +++ b/test/extension/toolbox/CMakeLists.txt @@ -24,7 +24,8 @@ foreach(_name is_bit_aligned is_homogeneous pixel_bit_size - subchroma_image) + subchroma_image + pattern) set(_test t_ext_toolbox_${_name}) set(_target test_ext_toolbox_${_name}) diff --git a/test/extension/toolbox/Jamfile b/test/extension/toolbox/Jamfile index a2a78f7bed..f56905e668 100644 --- a/test/extension/toolbox/Jamfile +++ b/test/extension/toolbox/Jamfile @@ -27,6 +27,7 @@ run color_convert_lab.cpp ; run color_convert_luminance.cpp ; run color_convert_xyz.cpp ; run indexed_image.cpp ; +run pattern.cpp ; # TODO: Add subchroma_image.cpp after fixing run-time failure, # for details see https://github.com/boostorg/gil/pull/164 diff --git a/test/extension/toolbox/pattern.cpp b/test/extension/toolbox/pattern.cpp new file mode 100644 index 0000000000..b8128f9152 --- /dev/null +++ b/test/extension/toolbox/pattern.cpp @@ -0,0 +1,237 @@ +// +// Copyright 2021 Prathamesh Tagore +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +// Reference for test case was taken from +// https://github.com/tuttleofx/TuttleOFX/blob/develop/libraries/boostHack/boost/gil/extension/toolbox/pattern.tests.cpp + +#include +#include +#include + +namespace gil = boost::gil; + +// This function helps us fill pixels of a rgb view given as 2nd argument with +// elements of the vector given as 1st argument. +void pixel_fill_rgb(std::vector>>& vec, + gil::rgb8_image_t& img) +{ + for (std::ptrdiff_t view_row = 0; view_row < view(img).height(); ++view_row) + { + for (std::ptrdiff_t view_col = 0; view_col < view(img).width(); ++view_col) + { + gil::view(img)(view_col, view_row) = gil::rgb8_pixel_t(vec[view_row][view_col][0], + vec[view_row][view_col][1], vec[view_row][view_col][2]); + } + } +} + +int main() +{ + std::vector>> original_img_vector { + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}} +}; + + std::vector>> expected_img_vector { + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0} ,{ 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, + { 0, 0, 0}, { 0, 0, 0}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}}, + {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, + {255, 255, 255}, {255, 255, 255}, {255, 255, 255}} +}; + + gil::rgb8_image_t original_img(16, 16), expected_img(33, 17), obtained_img(33, 17); + gil::rgb8_view_t original_img_view = gil::view(original_img); + gil::rgb8_view_t obtained_img_view = gil::view(obtained_img); + + pixel_fill_rgb(original_img_vector, original_img); + pixel_fill_rgb(expected_img_vector, expected_img); + + gil::pattern pattern(original_img_view); + pattern(obtained_img_view); + + BOOST_TEST(gil::equal_pixels(obtained_img_view, gil::view(expected_img))); + + return boost::report_errors(); +} From 4c06300d08d126589a55ef4c0a0855891cc7aff6 Mon Sep 17 00:00:00 2001 From: meshtag Date: Thu, 18 Mar 2021 12:10:11 +0530 Subject: [PATCH 08/14] Remove unnecessary namespace resolution --- include/boost/gil/extension/toolbox/metafunctions/pattern.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp index b18ef1c3d3..7272d62e41 100644 --- a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -53,7 +53,7 @@ struct pattern view_t v3 = subimage_view(view, x, y, aw, ah); view_t v4 = subimage_view(v2, 0, 0, aw, ah); - boost::gil::copy_pixels(v4, v3); + copy_pixels(v4, v3); } } } From 368ada59f2a438eccec7cbbf0bf8d2fe410a479f Mon Sep 17 00:00:00 2001 From: meshtag Date: Thu, 18 Mar 2021 12:37:56 +0530 Subject: [PATCH 09/14] Use better variable types --- .../extension/toolbox/metafunctions/pattern.hpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp index 7272d62e41..609a54be8b 100644 --- a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -24,8 +24,7 @@ struct pattern { using namespace boost::gil; - int h = v2.height(); - int w = v2.width(); + std::size_t h = v2.height(), w = v2.width(); // For ensuring that view passed through '()' operator has larger dimensions than view // passed through the constructor. @@ -33,21 +32,21 @@ struct pattern return; int n = 0; - for(int x = 0; x < view.width(); x += w) + for(std::ptrdiff_t x = 0; x < view.width(); x += w) { - for(int y = 0; y < view.height(); y += h) + for(std::ptrdiff_t y = 0; y < view.height(); y += h) { - int aw = w; + std::ptrdiff_t aw = w; if(x + w > view.width()) { - int t = x + w - view.width(); + std::ptrdiff_t t = x + w - view.width(); aw = w - t; } - int ah = h; + std::ptrdiff_t ah = h; if(y + h > view.height()) { - int t = y + h - view.height(); + std::ptrdiff_t t = y + h - view.height(); ah = h - t; } From e14ce8140a890ef8874f19363cf17de886078740 Mon Sep 17 00:00:00 2001 From: meshtag Date: Thu, 18 Mar 2021 12:53:06 +0530 Subject: [PATCH 10/14] Improve error catching mechanism --- .../gil/extension/toolbox/metafunctions/pattern.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp index 609a54be8b..d158c149a8 100644 --- a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -26,12 +26,15 @@ struct pattern std::size_t h = v2.height(), w = v2.width(); - // For ensuring that view passed through '()' operator has larger dimensions than view - // passed through the constructor. + // For ensuring that view passed through '()' operator has dimensions greater than or + // equal to the dimensions of view passed through constructor. if(h > view.height() || w > view.width()) - return; + { + throw std::length_error("Image view passed through overloaded '()' operator must have" + " dimensions greater than or equal to the dimensions of image view passed through" + " struct constructor"); + } - int n = 0; for(std::ptrdiff_t x = 0; x < view.width(); x += w) { for(std::ptrdiff_t y = 0; y < view.height(); y += h) From f7ef520074e22003b119fd7cbfc9bc4690595605 Mon Sep 17 00:00:00 2001 From: meshtag Date: Wed, 24 Mar 2021 10:06:51 +0530 Subject: [PATCH 11/14] Improve formatting --- .../extension/toolbox/metafunctions/pattern.hpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp index d158c149a8..ab35cdfc73 100644 --- a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -7,7 +7,7 @@ #include -namespace boost { namespace gil { +namespace boost { namespace gil { /// \brief Repeatedly copies smaller image view passed through the struct constructor in subimage /// views of the larger image view passed through overloaded '()' operator. @@ -28,26 +28,26 @@ struct pattern // For ensuring that view passed through '()' operator has dimensions greater than or // equal to the dimensions of view passed through constructor. - if(h > view.height() || w > view.width()) + if (h > view.height() || w > view.width()) { throw std::length_error("Image view passed through overloaded '()' operator must have" " dimensions greater than or equal to the dimensions of image view passed through" " struct constructor"); } - for(std::ptrdiff_t x = 0; x < view.width(); x += w) + for (std::ptrdiff_t x = 0; x < view.width(); x += w) { - for(std::ptrdiff_t y = 0; y < view.height(); y += h) + for (std::ptrdiff_t y = 0; y < view.height(); y += h) { std::ptrdiff_t aw = w; - if(x + w > view.width()) + if (x + w > view.width()) { std::ptrdiff_t t = x + w - view.width(); aw = w - t; } std::ptrdiff_t ah = h; - if(y + h > view.height()) + if (y + h > view.height()) { std::ptrdiff_t t = y + h - view.height(); ah = h - t; @@ -59,7 +59,6 @@ struct pattern } } } -}; -} } - +}; // pattern +}} // namespace boost::gil #endif From 216f956d226fdf8b1075011bba14efc3154f500c Mon Sep 17 00:00:00 2001 From: meshtag Date: Sat, 10 Apr 2021 08:46:42 +0530 Subject: [PATCH 12/14] Modified as per first review and compiler warnings suppression --- .../toolbox/metafunctions/pattern.hpp | 22 +++++++++---------- test/extension/toolbox/CMakeLists.txt | 4 ++-- test/extension/toolbox/pattern.cpp | 12 +++++----- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp index ab35cdfc73..23e8bdf541 100644 --- a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -2,8 +2,8 @@ // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef _pattern_hpp_ -#define _pattern_hpp_ +#ifndef BOOST_GIL_EXTENSION_TOOLBOX_METAFUNCTIONS_PATTERN_HPP +#define BOOST_GIL_EXTENSION_TOOLBOX_METAFUNCTIONS_PATTERN_HPP #include @@ -11,20 +11,18 @@ namespace boost { namespace gil { /// \brief Repeatedly copies smaller image view passed through the struct constructor in subimage /// views of the larger image view passed through overloaded '()' operator. -template +template struct pattern { - view_t v2; - pattern(view_t v2) - : v2(v2) + View v2; + pattern(View view) + : v2(view) { } - void operator()(view_t& view) + void operator()(View& view) { - using namespace boost::gil; - - std::size_t h = v2.height(), w = v2.width(); + long int const h = v2.height(), w = v2.width(); // For ensuring that view passed through '()' operator has dimensions greater than or // equal to the dimensions of view passed through constructor. @@ -53,8 +51,8 @@ struct pattern ah = h - t; } - view_t v3 = subimage_view(view, x, y, aw, ah); - view_t v4 = subimage_view(v2, 0, 0, aw, ah); + View v3 = subimage_view(view, x, y, aw, ah); + View v4 = subimage_view(v2, 0, 0, aw, ah); copy_pixels(v4, v3); } } diff --git a/test/extension/toolbox/CMakeLists.txt b/test/extension/toolbox/CMakeLists.txt index ff1d08b6c4..7951d02329 100644 --- a/test/extension/toolbox/CMakeLists.txt +++ b/test/extension/toolbox/CMakeLists.txt @@ -23,9 +23,9 @@ foreach(_name get_pixel_type is_bit_aligned is_homogeneous + pattern pixel_bit_size - subchroma_image - pattern) + subchroma_image) set(_test t_ext_toolbox_${_name}) set(_target test_ext_toolbox_${_name}) diff --git a/test/extension/toolbox/pattern.cpp b/test/extension/toolbox/pattern.cpp index b8128f9152..71c14656ae 100644 --- a/test/extension/toolbox/pattern.cpp +++ b/test/extension/toolbox/pattern.cpp @@ -17,22 +17,24 @@ namespace gil = boost::gil; // This function helps us fill pixels of a rgb view given as 2nd argument with // elements of the vector given as 1st argument. -void pixel_fill_rgb(std::vector>>& vec, +void pixel_fill_rgb(std::vector>>& vec, gil::rgb8_image_t& img) { for (std::ptrdiff_t view_row = 0; view_row < view(img).height(); ++view_row) { for (std::ptrdiff_t view_col = 0; view_col < view(img).width(); ++view_col) { - gil::view(img)(view_col, view_row) = gil::rgb8_pixel_t(vec[view_row][view_col][0], - vec[view_row][view_col][1], vec[view_row][view_col][2]); + gil::view(img)(view_col, view_row) = gil::rgb8_pixel_t( + static_cast(vec[view_row][view_col][0]), + static_cast(vec[view_row][view_col][1]), + static_cast(vec[view_row][view_col][2])); } } } int main() { - std::vector>> original_img_vector { + std::vector>> original_img_vector { {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, @@ -99,7 +101,7 @@ int main() {255, 255, 255}} }; - std::vector>> expected_img_vector { + std::vector>> expected_img_vector { {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, {255, 255, 255}, From ae8d9bbb6d997e0d77032ee153f956c1ff7a9cd9 Mon Sep 17 00:00:00 2001 From: meshtag Date: Sat, 10 Apr 2021 09:13:44 +0530 Subject: [PATCH 13/14] Improve variable handling --- .../toolbox/metafunctions/pattern.hpp | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp index 23e8bdf541..c0b6480bb2 100644 --- a/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions/pattern.hpp @@ -14,45 +14,39 @@ namespace boost { namespace gil { template struct pattern { - View v2; + View parent_view; pattern(View view) - : v2(view) + : parent_view(view) { } void operator()(View& view) { - long int const h = v2.height(), w = v2.width(); + long int const parent_view_height = parent_view.height(); + long int const parent_view_width = parent_view.width(); + long int const view_height = view.height(), view_width = view.width(); // For ensuring that view passed through '()' operator has dimensions greater than or // equal to the dimensions of view passed through constructor. - if (h > view.height() || w > view.width()) + if (parent_view_height > view_height || parent_view_width > view_width) { throw std::length_error("Image view passed through overloaded '()' operator must have" " dimensions greater than or equal to the dimensions of image view passed through" " struct constructor"); } - for (std::ptrdiff_t x = 0; x < view.width(); x += w) + for (std::ptrdiff_t x = 0; x < view_width; x += parent_view_width) { - for (std::ptrdiff_t y = 0; y < view.height(); y += h) + for (std::ptrdiff_t y = 0; y < view_height; y += parent_view_height) { - std::ptrdiff_t aw = w; - if (x + w > view.width()) - { - std::ptrdiff_t t = x + w - view.width(); - aw = w - t; - } - - std::ptrdiff_t ah = h; - if (y + h > view.height()) - { - std::ptrdiff_t t = y + h - view.height(); - ah = h - t; - } + std::ptrdiff_t aw = x + parent_view_width > view_width ? view_width - x : + parent_view_width; + + std::ptrdiff_t ah = y + parent_view_height > view_height ? view_height - y : + parent_view_height; View v3 = subimage_view(view, x, y, aw, ah); - View v4 = subimage_view(v2, 0, 0, aw, ah); + View v4 = subimage_view(parent_view, 0, 0, aw, ah); copy_pixels(v4, v3); } } From 1284963043095ab3593f3faa1ed388a993a67bf7 Mon Sep 17 00:00:00 2001 From: meshtag Date: Thu, 15 Apr 2021 15:15:06 +0530 Subject: [PATCH 14/14] Provide alphabetical ordering in build instruction files Provide alphabetical ordering in build instruction files --- include/boost/gil/extension/toolbox/metafunctions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/gil/extension/toolbox/metafunctions.hpp b/include/boost/gil/extension/toolbox/metafunctions.hpp index 21457b5fdf..86f507c1d0 100644 --- a/include/boost/gil/extension/toolbox/metafunctions.hpp +++ b/include/boost/gil/extension/toolbox/metafunctions.hpp @@ -15,7 +15,7 @@ #include #include #include -#include #include +#include #endif