segmentation
All Data Structures Namespaces Files Functions Variables Modules Pages
centsur.cpp
1 /*
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
3  * Authors: Vadim Tikhanoff
4  * email: vadim.tikhanoff@iit.it
5  * website: www.robotcub.org
6  * Permission is granted to copy, distribute, and/or modify this program
7  * under the terms of the GNU General Public License, version 2 or any
8  * later version published by the Free Software Foundation.
9  *
10  * A copy of the license can be found at
11  * http://www.robotcub.org/icub/license/gpl.txt
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details
17  */
18 
19 #include <math.h>
20 #include <iostream>
21 #include <stdlib.h>
22 #include "centsur.h"
23 
24 #define KERNSIZE 3 //kernsize (odd, >= 3)
25 
26 using namespace std;
27 
28 CentSur::CentSur(cv::Size tmpSize,int tmpGauss, double tmpSigma)
29 {
30  srcSize = tmpSize;
31  ngauss = 0;
32  ngauss = tmpGauss;
33  sigma = tmpSigma;
34  psize = (cv::Size*)malloc(ngauss*sizeof(cv::Size));
35  proi = (cv::Rect*)malloc(ngauss*sizeof(cv::Rect));
36 
37  for (int ng=0;ng<ngauss;ng++)
38  {
39  psize[ng].width = (int)ceil( ( (double)srcSize.width ) / double( 1<<ng ) );
40  psize[ng].height = (int)ceil( ( ((double)srcSize.height) / ( (double)srcSize.width) ) * psize[ng].width );
41  proi[ng].x = 0;
42  proi[ng].y = 0;
43  proi[ng].width = psize[ng].width;
44  proi[ng].height = psize[ng].height;
45  pyramid[ng] = cv::Mat ( psize[ng].height, psize[ng].width, CV_32FC1 );
46  pyramid_gauss[ng] = cv::Mat ( psize[ng].height, psize[ng].width, CV_32FC1 );
47  gauss[ng] = cv::Mat ( srcSize.height, srcSize.width, CV_32FC1 );
48 
49  }
50  img_32f = cv::Mat ( srcSize.height, srcSize.width, CV_32FC1 );
51  csTot32f = cv::Mat ( srcSize.height, srcSize.width, CV_32FC1 );
52  csTot32fTmp = cv::Mat ( srcSize.height, srcSize.width, CV_32FC1 );
53  csTot8u = cv::Mat ( srcSize.height, srcSize.width, CV_8UC1 );
54 }
55 
56 CentSur::~CentSur()
57 {
58 
59  free(psize);
60  free(proi);
61 
62  for (int ng=0;ng<ngauss;ng++)
63  {
64  pyramid[ng].release();
65  pyramid_gauss[ng].release();
66  gauss[ng].release();
67  }
68 
69  img_32f.release();
70  csTot32f.release();
71  csTot8u.release();
72  csTot32fTmp.release();
73 }
74 
75 void CentSur::proc_im_8u( const cv::Mat &img_8u )
76 {
77  //convert im precision to 32f:
78  img_8u.convertTo( img_32f, CV_32FC1, 1.0/255.0 );
79  //process as normal:
80  proc_im_32f( img_32f );
81 }
82 
83 void CentSur::proc_im_32f( const cv::Mat &im_32f )
84 {
85  //make image & gauss pyramids:
86  make_pyramid( im_32f );
87 
88  //reset tot cs_tot_tmp:
89  csTot32f.setTo( cv::Scalar(0) );
90 
91  //subtractions (ABSDIFF) to make DOG pyramid:
92  //1st neighbours:
93  for (int nd=0; nd<ngauss-1; nd++)
94  {
95  cv::absdiff( gauss[nd], gauss[nd+1], csTot32fTmp);
96  cv::add(csTot32fTmp, csTot32f, csTot32f);
97  }
98 
99  //2nd neighbours:
100  for (int ndd=0;ndd<ngauss-2;ndd++)
101  {
102  cv::absdiff( gauss[ndd], gauss[ndd+2], csTot32fTmp);
103  cv::add(csTot32fTmp, csTot32f, csTot32f);
104  }
105  /*//norm8u:
106  double min, max;
107  min = 0.0f;
108  max = 0.0f;
109  cv::minMaxLoc(csTot32f, &min, &max);
110  if (max == min){max=255.0f;min=0.0f;}*/
111 
112  //convert back to 8u with scale
113  csTot32f.convertTo( csTot8u, CV_8UC1, 1.0 * 255.0 );
114 }
115 
116 void CentSur::make_pyramid( const cv::Mat &im_32f )
117 {
118  //copy im to pyramid[0]:
119  im_32f.copyTo( pyramid[0] );
120  //filter first pyramid:
121  cv::Point anchor(-1,-1);
122  cv::Size ksize(KERNSIZE, KERNSIZE);
123  cv::boxFilter(pyramid[0], pyramid_gauss[0],-1, ksize, anchor, true, cv::BORDER_REPLICATE);
124  //cv::GaussianBlur(pyramid[0], pyramid_gauss[0], cv::Size(1, 1), sigma, 0.0, cv::BORDER_REPLICATE );
125  //copy filter output to gauss:
126  pyramid_gauss[0].copyTo( gauss[0] );
127 
128  double sd = 0.5;
129  double su = 2.0;
130 
131  for (int sg=1;sg<ngauss;sg++)
132  {
133  //Downsize previous pyramid image by half:
134  cv::resize(pyramid[sg-1], pyramid[sg], cv::Size(proi[sg].width, proi[sg].height), sd, sd, cv::INTER_LANCZOS4);
135  //filter:
136  cv::Point anchor(-1,-1);
137  cv::Size ksize(KERNSIZE, KERNSIZE);
138  cv::boxFilter(pyramid[sg], pyramid_gauss[sg],-1, ksize, anchor, true, cv::BORDER_REPLICATE);
139  //cv::GaussianBlur(pyramid[sg], pyramid_gauss[sg], cv::Size(1, 1), sigma, 0.0, cv::BORDER_REPLICATE );
140  su = double(1<< sg);
141  //Upsize and store to gauss:
142  cv::resize(pyramid_gauss[sg], gauss[sg], srcSize/*cv::Size(proi[sg].width,proi[sg].height)*/, su, su, cv::INTER_LANCZOS4);
143 //cv::INTER_LANCZOS4 INTER_CUBIC
144  }
145 }
146 
147 
An implementation modelling the centre-surround response, used for construction of spatial uniqueness...