bool QuickHarrisDetector::quickConvolutionWithBestPoint(
		    const image::ConvexRoi & roi, int pixMax[2], float & scoreMax) {
			
			int shift_derv = 1;
			int shift_derv_conv = shift_derv + shift_conv;

			// bounds
			int riMin = shift_derv_conv;
			int riMax = roi.h() - shift_derv_conv;
			int rjMin = shift_derv_conv;
			int rjMax = roi.w() - shift_derv_conv;

			// data structure pointers
			HQuickData* int_center;
#if GAUSSIAN_MASK_APPROX
#else
			HQuickData* int_upLeft;
			HQuickData* int_upRight;
			HQuickData* int_downLeft;
			HQuickData* int_downRight;
#endif

			float im_low_curv_max = 0.; // maximum smallest eigenvalue
			float im_high_curv_max = 0.;

			int sm, df; // sum and difference
			float sr, corner_ratio;
			int ri, rj; // roi coordinates

			for (ri = riMin; ri < riMax; ri++) {

				int_center = m_quickData + (ri * roi.w()) + rjMin;

#if GAUSSIAN_MASK_APPROX
				for(int i = 0; i < nConvCoeffs; ++i)
				{
					int_upLeft[i] = int_center - (shift_convs[i] * (roi.w()+1));
					int_upRight[i] = int_center - (shift_convs[i] * (roi.w()-1));
					int_downLeft[i] = int_center + (shift_convs[i] * (roi.w()-1));
					int_downRight[i] = int_center + (shift_convs[i] * (roi.w()+1));
				}
#else
				int_upLeft = int_center - (shift_conv * roi.w()) - shift_conv;
				int_upRight = int_center - (shift_conv * roi.w()) + shift_conv;
				int_downLeft = int_center + (shift_conv * roi.w()) - shift_conv;
				int_downRight = int_center + (shift_conv * roi.w()) + shift_conv;
#endif

				for (rj = rjMin; rj < rjMax; rj++) {

#if GAUSSIAN_MASK_APPROX
					int_center->im_conv_xx = int_center->im_conv_xy = int_center->im_conv_yy = 0.;
					for(int i = 0; i < nConvCoeffs; ++i)
					{
						int_center->im_conv_xx += convCoeffs[i]*(
							int_downRight[i]->int_xx - int_upRight[i]->int_xx -
							int_downLeft[i]->int_xx + int_upLeft[i]->int_xx);
						int_center->im_conv_xy += convCoeffs[i]*(
							int_downRight[i]->int_xy - int_upRight[i]->int_xy -
							int_downLeft[i]->int_xy + int_upLeft[i]->int_xy);
						int_center->im_conv_yy += convCoeffs[i]*(
							int_downRight[i]->int_yy - int_upRight[i]->int_yy -
							int_downLeft[i]->int_yy + int_upLeft[i]->int_yy);
					} 
					if (nConvCoeffsCenter)
					{
						int_center->im_conv_xx += convCoeffs[nConvCoeffs]*int_center->im_xx;
						int_center->im_conv_xy += convCoeffs[nConvCoeffs]*int_center->im_xy;
						int_center->im_conv_yy += convCoeffs[nConvCoeffs]*int_center->im_yy;
					}
#else
					int_center->im_conv_xx = int_downRight->int_xx - int_upRight->int_xx
					    - int_downLeft->int_xx + int_upLeft->int_xx;
					int_center->im_conv_xy = int_downRight->int_xy - int_upRight->int_xy
					    - int_downLeft->int_xy + int_upLeft->int_xy;
					int_center->im_conv_yy = int_downRight->int_yy - int_upRight->int_yy
					    - int_downLeft->int_yy + int_upLeft->int_yy;
#endif
					
					// get eigenvalues: EIG/eig = I_xx + I_yy +/- sqrt((Ixx - I_yy)^2 + 4*I_xy^2)
					sm = int_center->im_conv_xx + int_center->im_conv_yy;
					df = int_center->im_conv_xx - int_center->im_conv_yy;

					sr = sqrt((double) ((double) df * (double) df + 4
					    * ((double) int_center->im_conv_xy)
					    * ((double) int_center->im_conv_xy)));

					int_center->im_high_curv = (double) sm + sr; // Smallest eigenvalue.
					int_center->im_low_curv = (double) sm - sr; // Largest eigenvalue.

					// detect and write pixel corresponding to strongest corner, with score.
					#ifndef JFR_NDEBUG
					if (int_center->im_low_curv == 0.0) corner_ratio = 1e10; else
					#endif
					corner_ratio = int_center->im_high_curv / int_center->im_low_curv; // CAUTION should be high/low
					if (corner_ratio < m_edge) {
						if (int_center->im_low_curv > im_low_curv_max) {
							im_low_curv_max = int_center->im_low_curv;
							im_high_curv_max = int_center->im_high_curv;
							pixMax[0] = roi.x() + rj;
							pixMax[1] = roi.y() + ri;
						}
					}

					int_center++;
#if GAUSSIAN_MASK_APPROX
					for(int i = 0; i < nConvCoeffs; ++i)
					{
						int_upLeft[i]++;
						int_upRight[i]++;
						int_downLeft[i]++;
						int_downRight[i]++;
					}
#else
					int_upLeft++;
					int_upRight++;
					int_downLeft++;
					int_downRight++;
#endif

				}
			}

			// normalized score: over the size of the derivative and convolution windows
			scoreMax = sqrt(im_low_curv_max / normCoeff);

			//std::cout << "- at " << pixMax[0] << "," << pixMax[1] << " : high "  << im_high_curv_max << " low " << im_low_curv_max << " ; ratio " << im_high_curv_max/im_low_curv_max << " score " << scoreMax << std::endl;
			
#if FILTER_VIRTUAL_POINTS
/*
accept:
_|_   (4)        |_      _/    _     (2)      _   _   _  (1 or 2)
 |                              \             \   /
reject:
  |_     (3)    .  (0)
  |
*/
			
			int_center = m_quickData + ((pixMax[1]-roi.y()) * roi.w()) + (pixMax[0]-roi.x());
			
			int indexes[8][2] = {{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
			int radius = m_convolutionSize/2;
			for(int i = 0; i < 8; ++i) for(int j = 0; j < 2; ++j) indexes[i][j] *= radius;
			double thres = im_low_curv_max * 0.75;
			
			int npeaks = 0;
			bool lastpeaked = false;
			bool firstpeaked = false;
			for(int i = 0; i < 8; ++i)
			{
				int_upLeft = int_center + indexes[i][1] * roi.w() + indexes[i][0];
				
				if (int_upLeft->im_high_curv > thres)
				{
					if (i == 0) firstpeaked = true; else
					if (i == 7) lastpeaked = lastpeaked || firstpeaked;
					
					if (!lastpeaked) npeaks++; lastpeaked = true;
					
				} else
					lastpeaked = false;
std::cout << "  high " << int_upLeft->im_high_curv << " "  << " low " << int_upLeft->im_low_curv << std::endl;
			}
			bool ok = (npeaks == 1 || npeaks == 2 || npeaks == 4);
			
			std::cout << "  high " << int_center->im_high_curv << " low " << int_center->im_low_curv << " npeaks " << npeaks << " ok " << ok << std::endl;
#endif
			return (scoreMax > m_threshold);

		}
Beispiel #2
0
		void ActiveSearchGrid::setFailed(const image::ConvexRoi & roi)
		{
			vec2 p; p(0) = roi.x()+roi.w()/2; p(1) = roi.y()+roi.h()/2;
			veci2 cell = pix2cell(p);
			projectionsCount(cell(0), cell(1)) = -1;
		}
		void QuickHarrisDetector::quickDerivatives(
		    const jafar::image::Image & image, image::ConvexRoi & roi) {
			const uchar* pix_center;
			const uchar* pix_right;
			const uchar* pix_left;
			const uchar* pix_down;
			const uchar* pix_up;

			HQuickData* int_center;
			HQuickData* int_up;
			HQuickData* int_upLeft;
			HQuickData* int_left;

			// dead zone due to derivative mask [-1 0 1]
			int shift_derv = 1; // = (3-1)/2

			// i: vert; j: horz  image coordinates
			int iMin = roi.y() + shift_derv;
			int iMax = roi.y() + roi.h() - shift_derv;
			
			// FIXME take into account possible convex part of roi x(i) and w(i) by moving this into the loop
			int jMin = roi.x() + shift_derv;
			int jMax = roi.x() + roi.w() - shift_derv;

			int i, j; // i, j: image coordinates
			int ri; // ri: vertical roi coordinate
			for (i = iMin; i < iMax; i++) {
				ri = i - roi.y();

				pix_center = image.data() + (i * image.step()) + jMin;
				pix_right = pix_center + 1;
				pix_left = pix_center - 1;
				pix_down = pix_center + image.step();
				pix_up = pix_center - image.step();

				int_center = m_quickData + (ri * roi.w()) + shift_derv;
				int_up = int_center - roi.w();
				int_upLeft = int_up - 1;
				int_left = int_center - 1;

				for (j = jMin; j < jMax; j++) {
					// Build x and y derivatives, and their products: xx, xy and yy.
					int_center->im_x = *pix_right - *pix_left;
					int_center->im_y = *pix_down - *pix_up;
					int_center->im_xx = int_center->im_x * int_center->im_x;
					int_center->im_xy = int_center->im_x * int_center->im_y;
					int_center->im_yy = int_center->im_y * int_center->im_y;

					// build integral images of the 3 derivative products, xx, xy and yy:
					if (i == iMin && j == jMin) {
						int_center->int_xx = int_center->im_xx;
						int_center->int_xy = int_center->im_xy;
						int_center->int_yy = int_center->im_yy;
					} else if (i == iMin) {
						int_center->int_xx = int_center->im_xx + int_left->int_xx;
						int_center->int_xy = int_center->im_xy + int_left->int_xy;
						int_center->int_yy = int_center->im_yy + int_left->int_yy;
					} else if (j == jMin) {
						int_center->int_xx = int_center->im_xx + int_up->int_xx;
						int_center->int_xy = int_center->im_xy + int_up->int_xy;
						int_center->int_yy = int_center->im_yy + int_up->int_yy;
					} else {
						int_center->int_xx = int_center->im_xx + int_up->int_xx
						    + int_left->int_xx - int_upLeft->int_xx;
						int_center->int_xy = int_center->im_xy + int_up->int_xy
						    + int_left->int_xy - int_upLeft->int_xy;
						int_center->int_yy = int_center->im_yy + int_up->int_yy
						    + int_left->int_yy - int_upLeft->int_yy;
					}
					// Advance all pointers
					pix_center++;
					pix_right++;
					pix_left++;
					pix_up++;
					pix_down++;

					int_center++;
					int_up++;
					int_left++;
					int_upLeft++;

				}
			}

		}