double calcGlobalOrientation( InputArray _orientation, InputArray _mask, InputArray _mhi, double /*timestamp*/, double duration ) { Mat orient = _orientation.getMat(), mask = _mask.getMat(), mhi = _mhi.getMat(); Size size = mhi.size(); CV_Assert( mask.type() == CV_8U && orient.type() == CV_32F && mhi.type() == CV_32F ); CV_Assert( mask.size() == size && orient.size() == size ); CV_Assert( duration > 0 ); int histSize = 12; float _ranges[] = { 0.f, 360.f }; const float* ranges = _ranges; Mat hist; calcHist(&orient, 1, 0, mask, hist, 1, &histSize, &ranges); // find the maximum index (the dominant orientation) Point baseOrientPt; minMaxLoc(hist, 0, 0, 0, &baseOrientPt); float fbaseOrient = (baseOrientPt.x + baseOrientPt.y)*360.f/histSize; // override timestamp with the maximum value in MHI double timestamp = 0; minMaxLoc( mhi, 0, ×tamp, 0, 0, mask ); // find the shift relative to the dominant orientation as weighted sum of relative angles float a = (float)(254. / 255. / duration); float b = (float)(1. - timestamp * a); float delbound = (float)(timestamp - duration); if( mhi.isContinuous() && mask.isContinuous() && orient.isContinuous() ) { size.width *= size.height; size.height = 1; } /* a = 254/(255*dt) b = 1 - t*a = 1 - 254*t/(255*dur) = (255*dt - 254*t)/(255*dt) = (dt - (t - dt)*254)/(255*dt); -------------------------------------------------------- ax + b = 254*x/(255*dt) + (dt - (t - dt)*254)/(255*dt) = (254*x + dt - (t - dt)*254)/(255*dt) = ((x - (t - dt))*254 + dt)/(255*dt) = (((x - (t - dt))/dt)*254 + 1)/255 = (((x - low_time)/dt)*254 + 1)/255 */ float shiftOrient = 0, shiftWeight = 0; for( int y = 0; y < size.height; y++ ) { const float* mhiptr = mhi.ptr<float>(y); const float* oriptr = orient.ptr<float>(y); const uchar* maskptr = mask.ptr<uchar>(y); for( int x = 0; x < size.width; x++ ) { if( maskptr[x] != 0 && mhiptr[x] > delbound ) { /* orient in 0..360, base_orient in 0..360 -> (rel_angle = orient - base_orient) in -360..360. rel_angle is translated to -180..180 */ float weight = mhiptr[x] * a + b; float relAngle = oriptr[x] - fbaseOrient; relAngle += (relAngle < -180 ? 360 : 0); relAngle += (relAngle > 180 ? -360 : 0); if( fabs(relAngle) < 45 ) { shiftOrient += weight * relAngle; shiftWeight += weight; } } } } // add the dominant orientation and the relative shift if( shiftWeight == 0 ) shiftWeight = 0.01f; fbaseOrient += shiftOrient / shiftWeight; fbaseOrient -= (fbaseOrient < 360 ? 0 : 360); fbaseOrient += (fbaseOrient >= 0 ? 0 : 360); return fbaseOrient; }
bool cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints, InputArray _cameraMatrix, InputArray _distCoeffs, OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess, int iterationsCount, float reprojectionError, double confidence, OutputArray _inliers, int flags) { Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat(); int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F)); CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) ); CV_Assert(opoints.isContinuous()); CV_Assert(opoints.depth() == CV_32F || opoints.depth() == CV_64F); CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3); CV_Assert(ipoints.isContinuous()); CV_Assert(ipoints.depth() == CV_32F || ipoints.depth() == CV_64F); CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2); _rvec.create(3, 1, CV_64FC1); _tvec.create(3, 1, CV_64FC1); Mat rvec = useExtrinsicGuess ? _rvec.getMat() : Mat(3, 1, CV_64FC1); Mat tvec = useExtrinsicGuess ? _tvec.getMat() : Mat(3, 1, CV_64FC1); Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); Ptr<PointSetRegistrator::Callback> cb; // pointer to callback cb = makePtr<PnPRansacCallback>( cameraMatrix, distCoeffs, flags, useExtrinsicGuess, rvec, tvec); int model_points = 4; // minimum of number of model points if( flags == cv::SOLVEPNP_ITERATIVE ) model_points = 6; else if( flags == cv::SOLVEPNP_UPNP ) model_points = 6; else if( flags == cv::SOLVEPNP_EPNP ) model_points = 5; double param1 = reprojectionError; // reprojection error double param2 = confidence; // confidence int param3 = iterationsCount; // number maximum iterations cv::Mat _local_model(3, 2, CV_64FC1); cv::Mat _mask_local_inliers(1, opoints.rows, CV_8UC1); // call Ransac int result = createRANSACPointSetRegistrator(cb, model_points, param1, param2, param3)->run(opoints, ipoints, _local_model, _mask_local_inliers); if( result <= 0 || _local_model.rows <= 0) { _rvec.assign(rvec); // output rotation vector _tvec.assign(tvec); // output translation vector if( _inliers.needed() ) _inliers.release(); return false; } else { _rvec.assign(_local_model.col(0)); // output rotation vector _tvec.assign(_local_model.col(1)); // output translation vector } if(_inliers.needed()) { Mat _local_inliers; int count = 0; for (int i = 0; i < _mask_local_inliers.rows; ++i) { if((int)_mask_local_inliers.at<uchar>(i) == 1) // inliers mask { _local_inliers.push_back(count); // output inliers vector count++; } } _local_inliers.copyTo(_inliers); } return true; }
int RegionSaliency::Quantize(const Mat& img3f, Mat &idx1i, Mat &_color3f, Mat &_colorNum, double ratio) { static const int clrNums[3] = {12, 12, 12}; static const float clrTmp[3] = {clrNums[0] - 0.0001f, clrNums[1] - 0.0001f, clrNums[2] - 0.0001f}; static const int w[3] = {clrNums[1] * clrNums[2], clrNums[2], 1}; CV_Assert(img3f.data != NULL); idx1i = Mat::zeros(img3f.size(), CV_32S); int rows = img3f.rows, cols = img3f.cols; if (img3f.isContinuous() && idx1i.isContinuous()) { cols *= rows; rows = 1; } // Build color pallet map<int, int> pallet; for (int y = 0; y < rows; y++) { const float* imgData = img3f.ptr<float>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++, imgData += 3) { idx[x] = (int)(imgData[0]*clrTmp[0])*w[0] + (int)(imgData[1]*clrTmp[1])*w[1] + (int)(imgData[2]*clrTmp[2]); pallet[idx[x]] ++; } } // Find significant colors int maxNum = 0; { int count = 0; vector<pair<int, int> > num; // (num, color) pairs in num num.reserve(pallet.size()); for (map<int, int>::iterator it = pallet.begin(); it != pallet.end(); it++) num.push_back(pair<int, int>(it->second, it->first)); // (color, num) pairs in pallet sort(num.begin(), num.end(), std::greater<pair<int, int> >()); maxNum = (int)num.size(); int maxDropNum = cvRound(rows * cols * (1-ratio)); for (int crnt = num[maxNum-1].first; crnt < maxDropNum && maxNum > 1; maxNum--) crnt += num[maxNum - 2].first; maxNum = min(maxNum, 256); // To avoid very rarely case if (maxNum < 10) maxNum = min((int)pallet.size(), 100); pallet.clear(); for (int i = 0; i < maxNum; i++) pallet[num[i].second] = i; vector<Vec3i> color3i(num.size()); for (unsigned int i = 0; i < num.size(); i++) { color3i[i][0] = num[i].second / w[0]; color3i[i][1] = num[i].second % w[0] / w[1]; color3i[i][2] = num[i].second % w[1]; } for (unsigned int i = maxNum; i < num.size(); i++) { int simIdx = 0, simVal = INT_MAX; for (int j = 0; j < maxNum; j++) { int d_ij = vecSqrDist3(color3i[i], color3i[j]); if (d_ij < simVal) simVal = d_ij, simIdx = j; } pallet[num[i].second] = pallet[num[simIdx].second]; } } _color3f = Mat::zeros(1, maxNum, CV_32FC3); _colorNum = Mat::zeros(_color3f.size(), CV_32S); Vec3f* color = (Vec3f*)(_color3f.data); int* colorNum = (int*)(_colorNum.data); for (int y = 0; y < rows; y++) { const Vec3f* imgData = img3f.ptr<Vec3f>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++) { idx[x] = pallet[idx[x]]; color[idx[x]] += imgData[x]; colorNum[idx[x]] ++; } } for (int i = 0; i < _color3f.cols; i++) { color[i] *= (1.0f/((float)colorNum[i])); //color[i] /= ((float)colorNum[i]); // original code that caused trouble with newer versions; it seems like the division operator is ill defined } return _color3f.cols; }
static double getThreshVal_Otsu_8u( const Mat& _src ) { Size size = _src.size(); int step = (int) _src.step; if( _src.isContinuous() ) { size.width *= size.height; size.height = 1; step = size.width; } #if IPP_VERSION_X100 >= 801 && !defined(HAVE_IPP_ICV_ONLY) CV_IPP_CHECK() { IppiSize srcSize = { size.width, size.height }; Ipp8u thresh; CV_SUPPRESS_DEPRECATED_START IppStatus ok = ippiComputeThreshold_Otsu_8u_C1R(_src.ptr(), step, srcSize, &thresh); CV_SUPPRESS_DEPRECATED_END if (ok >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return thresh; } setIppErrorStatus(); } #endif const int N = 256; int i, j, h[N] = {0}; for( i = 0; i < size.height; i++ ) { const uchar* src = _src.ptr() + step*i; j = 0; #if CV_ENABLE_UNROLLED for( ; j <= size.width - 4; j += 4 ) { int v0 = src[j], v1 = src[j+1]; h[v0]++; h[v1]++; v0 = src[j+2]; v1 = src[j+3]; h[v0]++; h[v1]++; } #endif for( ; j < size.width; j++ ) h[src[j]]++; } double mu = 0, scale = 1./(size.width*size.height); for( i = 0; i < N; i++ ) mu += i*(double)h[i]; mu *= scale; double mu1 = 0, q1 = 0; double max_sigma = 0, max_val = 0; for( i = 0; i < N; i++ ) { double p_i, q2, mu2, sigma; p_i = h[i]*scale; mu1 *= q1; q1 += p_i; q2 = 1. - q1; if( std::min(q1,q2) < FLT_EPSILON || std::max(q1,q2) > 1. - FLT_EPSILON ) continue; mu1 = (mu1 + i*p_i)/q1; mu2 = (mu - q1*mu1)/q2; sigma = q1*q2*(mu1 - mu2)*(mu1 - mu2); if( sigma > max_sigma ) { max_sigma = sigma; max_val = i; } } return max_val; }
void MyOpenCV::cvtColor(const Mat &matFrom, Mat &matTo, int code) { CvSize s = matFrom.size(); matTo = cvCreateMat(s.height, s.width, CV_8UC3); int w = s.width; int h = s.height; double S, V, L; double R, G, B, M, m, C, H=0; int channels = matFrom.channels(); switch(code) { case BGR2HSV: if(matFrom.isContinuous() && matTo.isContinuous()) { int size; uchar *to = matTo.ptr(0); const uchar *from = matFrom.ptr(0); size = w*h*channels; for(int i = 0; i < size; i += channels) { B = from[i]/255.; G = from[i+1]/255.; R = from[i+2]/255.; M = max(max(R,G),B); m = min(min(R,G),B); C = M - m; V = M; if(C == 0) { H = 0; S = 0; } else { if(M == R) H = fmod((G-B)/C,6); if(M == G) H = (B-R)/C+2; if(M == B) H = (R-G)/C+4; S = C/V; } H = H*255/6; S = S*255; V = V*255; to[i] = H; to[i+1] = S; to[i+2] = V; } } else { for(int i = 0; i < h; i++) for(int j = 0; j < w; j ++) { R = matFrom.ptr<Vec3b>(i)[j][2]/255.; G = matFrom.ptr<Vec3b>(i)[j][1]/255.; B = matFrom.ptr<Vec3b>(i)[j][0]/255.; M = max(max(R,G),B); m = min(min(R,G),B); C = M - m; V = M; if(C == 0) { H = 0; S = 0; } else { if(M == R) H = fmod((G-B)/C,6); if(M == G) H = (B-R)/C+2; if(M == B) H = (R-G)/C+4; S = C/V; } H = H*255/6; S = S*255; V = V*255; matTo.ptr<Vec3b>(i)[j][0] = H; matTo.ptr<Vec3b>(i)[j][1] = S; matTo.ptr<Vec3b>(i)[j][2] = V; } } break; case BGR2HSL: for(int i = 0; i < h; i++) for(int j = 0; j < w; j ++) { R = matFrom.ptr<Vec3b>(i)[j][2]/255.; G = matFrom.ptr<Vec3b>(i)[j][1]/255.; B = matFrom.ptr<Vec3b>(i)[j][0]/255.; M = max(max(R,G),B); m = min(min(R,G),B); C = M - m; L = (M+m)/2; if(C == 0) { H = 0; S = 0; } else { if(M == R) H = fmod((G-B)/C,6); if(M == G) H = (B-R)/C+2; if(M == B) H = (R-G)/C+4; S = C/(1-abs(2*L-1)); } H = H*255/6; S = S*255; L = L*255; matTo.ptr<Vec3b>(i)[j][0] = H; matTo.ptr<Vec3b>(i)[j][1] = L; matTo.ptr<Vec3b>(i)[j][2] = S; } break; default: break; } }
static void convertFromCCS( const Mat& _src0, const Mat& _src1, Mat& _dst, int flags ) { if( _dst.rows > 1 && (_dst.cols > 1 || (flags & DFT_ROWS)) ) { int i, count = _dst.rows, len = _dst.cols; bool is2d = (flags & DFT_ROWS) == 0; Mat src0row, src1row, dstrow; for( i = 0; i < count; i++ ) { int j = !is2d || i == 0 ? i : count - i; src0row = _src0.row(i); src1row = _src1.row(j); dstrow = _dst.row(i); convertFromCCS( src0row, src1row, dstrow, 0 ); } if( is2d ) { src0row = _src0.col(0); dstrow = _dst.col(0); convertFromCCS( src0row, src0row, dstrow, 0 ); if( (len & 1) == 0 ) { src0row = _src0.col(_src0.cols - 1); dstrow = _dst.col(len/2); convertFromCCS( src0row, src0row, dstrow, 0 ); } } } else { int i, n = _dst.cols + _dst.rows - 1, n2 = (n+1) >> 1; int cn = _src0.channels(); int srcstep = cn, dststep = 1; if( !_dst.isContinuous() ) dststep = (int)(_dst.step/_dst.elemSize()); if( !_src0.isContinuous() ) srcstep = (int)(_src0.step/_src0.elemSize1()); if( _dst.depth() == CV_32F ) { Complexf* dst = _dst.ptr<Complexf>(); const float* src0 = _src0.ptr<float>(); const float* src1 = _src1.ptr<float>(); int delta0, delta1; dst->re = src0[0]; dst->im = 0; if( (n & 1) == 0 ) { dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep]; dst[n2*dststep].im = 0; } delta0 = srcstep; delta1 = delta0 + (cn == 1 ? srcstep : 1); if( cn == 1 ) srcstep *= 2; for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep ) { float t0 = src0[delta0]; float t1 = src0[delta1]; dst[i*dststep].re = t0; dst[i*dststep].im = t1; t0 = src1[delta0]; t1 = -src1[delta1]; dst[(n-i)*dststep].re = t0; dst[(n-i)*dststep].im = t1; } } else { Complexd* dst = _dst.ptr<Complexd>(); const double* src0 = _src0.ptr<double>(); const double* src1 = _src1.ptr<double>(); int delta0, delta1; dst->re = src0[0]; dst->im = 0; if( (n & 1) == 0 ) { dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep]; dst[n2*dststep].im = 0; } delta0 = srcstep; delta1 = delta0 + (cn == 1 ? srcstep : 1); if( cn == 1 ) srcstep *= 2; for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep ) { double t0 = src0[delta0]; double t1 = src0[delta1]; dst[i*dststep].re = t0; dst[i*dststep].im = t1; t0 = src1[delta0]; t1 = -src1[delta1]; dst[(n-i)*dststep].re = t0; dst[(n-i)*dststep].im = t1; } } } }
static void thresh_16s( const Mat& _src, Mat& _dst, short thresh, short maxval, int type ) { int i, j; Size roi = _src.size(); roi.width *= _src.channels(); const short* src = _src.ptr<short>(); short* dst = _dst.ptr<short>(); size_t src_step = _src.step/sizeof(src[0]); size_t dst_step = _dst.step/sizeof(dst[0]); #if CV_SSE2 volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE); #endif if( _src.isContinuous() && _dst.isContinuous() ) { roi.width *= roi.height; roi.height = 1; src_step = dst_step = roi.width; } #ifdef HAVE_TEGRA_OPTIMIZATION if (tegra::thresh_16s(_src, _dst, roi.width, roi.height, thresh, maxval, type)) return; #endif #if defined(HAVE_IPP) CV_IPP_CHECK() { IppiSize sz = { roi.width, roi.height }; CV_SUPPRESS_DEPRECATED_START switch( type ) { case THRESH_TRUNC: #ifndef HAVE_IPP_ICV_ONLY if (_src.data == _dst.data && ippiThreshold_GT_16s_C1IR(dst, (int)dst_step*sizeof(dst[0]), sz, thresh) >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return; } #endif if (ippiThreshold_GT_16s_C1R(src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh) >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return; } setIppErrorStatus(); break; case THRESH_TOZERO: #ifndef HAVE_IPP_ICV_ONLY if (_src.data == _dst.data && ippiThreshold_LTVal_16s_C1IR(dst, (int)dst_step*sizeof(dst[0]), sz, thresh + 1, 0) >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return; } #endif if (ippiThreshold_LTVal_16s_C1R(src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh+1, 0) >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return; } setIppErrorStatus(); break; case THRESH_TOZERO_INV: #ifndef HAVE_IPP_ICV_ONLY if (_src.data == _dst.data && ippiThreshold_GTVal_16s_C1IR(dst, (int)dst_step*sizeof(dst[0]), sz, thresh, 0) >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return; } #endif if (ippiThreshold_GTVal_16s_C1R(src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh, 0) >= 0) { CV_IMPL_ADD(CV_IMPL_IPP); return; } setIppErrorStatus(); break; } CV_SUPPRESS_DEPRECATED_END } #endif switch( type ) { case THRESH_BINARY: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128i thresh8 = _mm_set1_epi16(thresh), maxval8 = _mm_set1_epi16(maxval); for( ; j <= roi.width - 16; j += 16 ) { __m128i v0, v1; v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); v0 = _mm_cmpgt_epi16( v0, thresh8 ); v1 = _mm_cmpgt_epi16( v1, thresh8 ); v0 = _mm_and_si128( v0, maxval8 ); v1 = _mm_and_si128( v1, maxval8 ); _mm_storeu_si128((__m128i*)(dst + j), v0 ); _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); } } #elif CV_NEON int16x8_t v_thresh = vdupq_n_s16(thresh), v_maxval = vdupq_n_s16(maxval); for( ; j <= roi.width - 8; j += 8 ) { uint16x8_t v_mask = vcgtq_s16(vld1q_s16(src + j), v_thresh); vst1q_s16(dst + j, vandq_s16(vreinterpretq_s16_u16(v_mask), v_maxval)); } #endif for( ; j < roi.width; j++ ) dst[j] = src[j] > thresh ? maxval : 0; } break; case THRESH_BINARY_INV: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128i thresh8 = _mm_set1_epi16(thresh), maxval8 = _mm_set1_epi16(maxval); for( ; j <= roi.width - 16; j += 16 ) { __m128i v0, v1; v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); v0 = _mm_cmpgt_epi16( v0, thresh8 ); v1 = _mm_cmpgt_epi16( v1, thresh8 ); v0 = _mm_andnot_si128( v0, maxval8 ); v1 = _mm_andnot_si128( v1, maxval8 ); _mm_storeu_si128((__m128i*)(dst + j), v0 ); _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); } } #elif CV_NEON int16x8_t v_thresh = vdupq_n_s16(thresh), v_maxval = vdupq_n_s16(maxval); for( ; j <= roi.width - 8; j += 8 ) { uint16x8_t v_mask = vcleq_s16(vld1q_s16(src + j), v_thresh); vst1q_s16(dst + j, vandq_s16(vreinterpretq_s16_u16(v_mask), v_maxval)); } #endif for( ; j < roi.width; j++ ) dst[j] = src[j] <= thresh ? maxval : 0; } break; case THRESH_TRUNC: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128i thresh8 = _mm_set1_epi16(thresh); for( ; j <= roi.width - 16; j += 16 ) { __m128i v0, v1; v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); v0 = _mm_min_epi16( v0, thresh8 ); v1 = _mm_min_epi16( v1, thresh8 ); _mm_storeu_si128((__m128i*)(dst + j), v0 ); _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); } } #elif CV_NEON int16x8_t v_thresh = vdupq_n_s16(thresh); for( ; j <= roi.width - 8; j += 8 ) vst1q_s16(dst + j, vminq_s16(vld1q_s16(src + j), v_thresh)); #endif for( ; j < roi.width; j++ ) dst[j] = std::min(src[j], thresh); } break; case THRESH_TOZERO: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128i thresh8 = _mm_set1_epi16(thresh); for( ; j <= roi.width - 16; j += 16 ) { __m128i v0, v1; v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); v0 = _mm_and_si128(v0, _mm_cmpgt_epi16(v0, thresh8)); v1 = _mm_and_si128(v1, _mm_cmpgt_epi16(v1, thresh8)); _mm_storeu_si128((__m128i*)(dst + j), v0 ); _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); } } #elif CV_NEON int16x8_t v_thresh = vdupq_n_s16(thresh); for( ; j <= roi.width - 8; j += 8 ) { int16x8_t v_src = vld1q_s16(src + j); uint16x8_t v_mask = vcgtq_s16(v_src, v_thresh); vst1q_s16(dst + j, vandq_s16(vreinterpretq_s16_u16(v_mask), v_src)); } #endif for( ; j < roi.width; j++ ) { short v = src[j]; dst[j] = v > thresh ? v : 0; } } break; case THRESH_TOZERO_INV: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128i thresh8 = _mm_set1_epi16(thresh); for( ; j <= roi.width - 16; j += 16 ) { __m128i v0, v1; v0 = _mm_loadu_si128( (const __m128i*)(src + j) ); v1 = _mm_loadu_si128( (const __m128i*)(src + j + 8) ); v0 = _mm_andnot_si128(_mm_cmpgt_epi16(v0, thresh8), v0); v1 = _mm_andnot_si128(_mm_cmpgt_epi16(v1, thresh8), v1); _mm_storeu_si128((__m128i*)(dst + j), v0 ); _mm_storeu_si128((__m128i*)(dst + j + 8), v1 ); } } #elif CV_NEON int16x8_t v_thresh = vdupq_n_s16(thresh); for( ; j <= roi.width - 8; j += 8 ) { int16x8_t v_src = vld1q_s16(src + j); uint16x8_t v_mask = vcleq_s16(v_src, v_thresh); vst1q_s16(dst + j, vandq_s16(vreinterpretq_s16_u16(v_mask), v_src)); } #endif for( ; j < roi.width; j++ ) { short v = src[j]; dst[j] = v <= thresh ? v : 0; } } break; default: return CV_Error( CV_StsBadArg, "" ); } }
void HDF5Impl::dsinsert( InputArray Array, const String& dslabel, const int* dims_offset, const int* dims_counts ) const { // only Mat support CV_Assert( Array.isMat() ); // check dataset exists if ( hlexists( dslabel ) == false ) CV_Error_(Error::StsInternal, ("Dataset '%s' does not exist.", dslabel.c_str())); Mat matrix = Array.getMat(); // memory array should be compact CV_Assert( matrix.isContinuous() ); int n_dims = matrix.dims; int channs = matrix.channels(); hsize_t *dsdims = new hsize_t[n_dims]; hsize_t *offset = new hsize_t[n_dims]; // replicate Mat dimensions for ( int d = 0; d < n_dims; d++ ) { offset[d] = 0; dsdims[d] = matrix.size[d]; } // set custom amount of data if ( dims_counts != NULL ) { for ( int d = 0; d < n_dims; d++ ) { CV_Assert( dims_counts[d] <= matrix.size[d] ); dsdims[d] = dims_counts[d]; } } // open dataset hid_t dsdata = H5Dopen( m_h5_file_id, dslabel.c_str(), H5P_DEFAULT ); // create input data space hid_t dspace = H5Screate_simple( n_dims, dsdims, NULL ); // set custom offsets if ( dims_offset != NULL ) { for ( int d = 0; d < n_dims; d++ ) offset[d] = dims_offset[d]; } // get actual file space and dims hid_t fspace = H5Dget_space( dsdata ); int f_dims = H5Sget_simple_extent_ndims( fspace ); hsize_t *fsdims = new hsize_t[f_dims]; H5Sget_simple_extent_dims( fspace, fsdims, NULL ); H5Sclose( fspace ); CV_Assert( f_dims == n_dims ); // compute new extents hsize_t *nwdims = new hsize_t[n_dims]; for ( int d = 0; d < n_dims; d++ ) { // init nwdims[d] = 0; // add offset if ( dims_offset != NULL ) nwdims[d] += dims_offset[d]; // add counts or matrix size if ( dims_counts != NULL ) nwdims[d] += dims_counts[d]; else nwdims[d] += matrix.size[d]; // clamp back if smaller if ( nwdims[d] < fsdims[d] ) nwdims[d] = fsdims[d]; } // extend dataset H5Dextend( dsdata, nwdims ); // get the extended data space fspace = H5Dget_space( dsdata ); H5Sselect_hyperslab( fspace, H5S_SELECT_SET, offset, NULL, dsdims, NULL ); // convert type hid_t dstype = GetH5type( matrix.type() ); // expand channs if ( matrix.channels() > 1 ) { hsize_t adims[1] = { (hsize_t)channs }; dstype = H5Tarray_create( dstype, 1, adims ); } // write into dataset H5Dwrite( dsdata, dstype, dspace, fspace, H5P_DEFAULT, matrix.data ); if ( matrix.channels() > 1 ) H5Tclose( dstype ); delete [] dsdims; delete [] offset; delete [] fsdims; delete [] nwdims; H5Sclose( dspace ); H5Sclose( fspace ); H5Dclose( dsdata ); }
void HDF5Impl::dswrite( InputArray Array, const String& dslabel, const int* dims_offset, const int* dims_counts ) const { // only Mat support CV_Assert( Array.isMat() ); Mat matrix = Array.getMat(); // memory array should be compact CV_Assert( matrix.isContinuous() ); int n_dims = matrix.dims; int channs = matrix.channels(); int *dsizes = new int[n_dims]; hsize_t *dsdims = new hsize_t[n_dims]; hsize_t *offset = new hsize_t[n_dims]; // replicate Mat dimensions for ( int d = 0; d < n_dims; d++ ) { offset[d] = 0; dsizes[d] = matrix.size[d]; dsdims[d] = matrix.size[d]; } // FixMe: If one of the groups the dataset belongs to does not exist, // FixMe: dscreate() will fail! // FixMe: It should be an error if the specified dataset has not been created instead of trying to create it // pre-create dataset if needed if ( hlexists( dslabel ) == false ) dscreate( n_dims, dsizes, matrix.type(), dslabel ); // set custom amount of data if ( dims_counts != NULL ) { for ( int d = 0; d < n_dims; d++ ) dsdims[d] = dims_counts[d]; } // open dataset hid_t dsdata = H5Dopen( m_h5_file_id, dslabel.c_str(), H5P_DEFAULT ); // create input data space hid_t dspace = H5Screate_simple( n_dims, dsdims, NULL ); // set custom offsets if ( dims_offset != NULL ) { for ( int d = 0; d < n_dims; d++ ) offset[d] = dims_offset[d]; } // create offset write window space hid_t fspace = H5Dget_space( dsdata ); H5Sselect_hyperslab( fspace, H5S_SELECT_SET, offset, NULL, dsdims, NULL ); // convert type hid_t dstype = GetH5type( matrix.type() ); // expand channs if ( matrix.channels() > 1 ) { hsize_t adims[1] = { (hsize_t)channs }; dstype = H5Tarray_create( dstype, 1, adims ); } // write into dataset H5Dwrite( dsdata, dstype, dspace, fspace, H5P_DEFAULT, matrix.data ); if ( matrix.channels() > 1 ) H5Tclose( dstype ); delete [] dsizes; delete [] dsdims; delete [] offset; H5Sclose( dspace ); H5Sclose( fspace ); H5Dclose( dsdata ); }
static void build3dmodel( const Ptr<FeatureDetector>& detector, const Ptr<DescriptorExtractor>& descriptorExtractor, const vector<Point3f>& /*modelBox*/, const vector<string>& imageList, const vector<Rect>& roiList, const vector<Vec6f>& poseList, const Mat& cameraMatrix, PointModel& model ) { int progressBarSize = 10; const double Feps = 5; const double DescriptorRatio = 0.7; vector<vector<KeyPoint> > allkeypoints; vector<int> dstart; vector<float> alldescriptorsVec; vector<Vec2i> pairwiseMatches; vector<Mat> Rs, ts; int descriptorSize = 0; Mat descriptorbuf; Set2i pairs, keypointsIdxMap; model.points.clear(); model.didx.clear(); dstart.push_back(0); size_t nimages = imageList.size(); size_t nimagePairs = (nimages - 1)*nimages/2 - nimages; printf("\nComputing descriptors "); // 1. find all the keypoints and all the descriptors for( size_t i = 0; i < nimages; i++ ) { vector<KeyPoint> keypoints; std::stringstream descriptorsPath; string algStringCode = "SURF"; descriptorsPath << imageList[i] << "." << algStringCode << ".xml"; cv::FileStorage fs(descriptorsPath.str().c_str(), FileStorage::READ); if( fs.isOpened()) { fs["descriptors"] >> descriptorbuf; cv::read( fs["keypoints"], keypoints); } fs.release(); //Point2f roiofs = roiList[i].tl(); //for( size_t k = 0; k < keypoints.size(); k++ ) // keypoints[k].pt += roiofs; allkeypoints.push_back(keypoints); // Mat img = imread(imageList[i], 1), gray; // cvtColor(img, gray, CV_BGR2GRAY); // // vector<KeyPoint> keypoints; // detector->detect(gray, keypoints); // descriptorExtractor->compute(gray, keypoints, descriptorbuf); // Point2f roiofs = roiList[i].tl(); // for( size_t k = 0; k < keypoints.size(); k++ ) // keypoints[k].pt += roiofs; // allkeypoints.push_back(keypoints); // Mat buf = descriptorbuf; if( !buf.isContinuous() || buf.type() != CV_32F ) { buf.release(); descriptorbuf.convertTo(buf, CV_32F); } descriptorSize = buf.cols; size_t prev = alldescriptorsVec.size(); size_t delta = buf.rows*buf.cols; alldescriptorsVec.resize(prev + delta); std::copy(buf.ptr<float>(), buf.ptr<float>() + delta, alldescriptorsVec.begin() + prev); dstart.push_back(dstart.back() + keypoints.size()); //Mat R, t; //unpackPose(poseList[i], R, t); //Rs.push_back(R); //ts.push_back(t); if( (i+1)*progressBarSize/nimages > i*progressBarSize/nimages ) { putchar('.'); fflush(stdout); } }
void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask ) { Mat src = _src.getMat(), mask = _mask.getMat(); CV_Assert( mask.empty() || mask.type() == CV_8U ); int k, cn = src.channels(), depth = src.depth(); SumSqrFunc func = sumSqrTab[depth]; CV_Assert( func != 0 ); const Mat* arrays[] = {&src, &mask, 0}; uchar* ptrs[2]; NAryMatIterator it(arrays, ptrs); int total = (int)it.size, blockSize = total, intSumBlockSize = 0; int j, count = 0, nz0 = 0; AutoBuffer<double> _buf(cn*4); double *s = (double*)_buf, *sq = s + cn; int *sbuf = (int*)s, *sqbuf = (int*)sq; bool blockSum = depth <= CV_16S, blockSqSum = depth <= CV_8S; size_t esz = 0; for( k = 0; k < cn; k++ ) s[k] = sq[k] = 0; if( blockSum ) { intSumBlockSize = 1 << 15; blockSize = std::min(blockSize, intSumBlockSize); sbuf = (int*)(sq + cn); if( blockSqSum ) sqbuf = sbuf + cn; for( k = 0; k < cn; k++ ) sbuf[k] = sqbuf[k] = 0; esz = src.elemSize(); } for( size_t i = 0; i < it.nplanes; i++, ++it ) { for( j = 0; j < total; j += blockSize ) { int bsz = std::min(total - j, blockSize); int nz = func( ptrs[0], ptrs[1], (uchar*)sbuf, (uchar*)sqbuf, bsz, cn ); count += nz; nz0 += nz; if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) ) { for( k = 0; k < cn; k++ ) { s[k] += sbuf[k]; sbuf[k] = 0; } if( blockSqSum ) { for( k = 0; k < cn; k++ ) { sq[k] += sqbuf[k]; sqbuf[k] = 0; } } count = 0; } ptrs[0] += bsz*esz; if( ptrs[1] ) ptrs[1] += bsz; } } double scale = nz0 ? 1./nz0 : 0.; for( k = 0; k < cn; k++ ) { s[k] *= scale; sq[k] = std::sqrt(std::max(sq[k]*scale - s[k]*s[k], 0.)); } for( j = 0; j < 2; j++ ) { const double* sptr = j == 0 ? s : sq; _OutputArray _dst = j == 0 ? _mean : _sdv; if( !_dst.needed() ) continue; if( !_dst.fixedSize() ) _dst.create(cn, 1, CV_64F, -1, true); Mat dst = _dst.getMat(); int dcn = (int)dst.total(); CV_Assert( dst.type() == CV_64F && dst.isContinuous() && (dst.cols == 1 || dst.rows == 1) && dcn >= cn ); double* dptr = dst.ptr<double>(); for( k = 0; k < cn; k++ ) dptr[k] = sptr[k]; for( ; k < dcn; k++ ) dptr[k] = 0; } }
void divSpectrums( InputArray _srcA, InputArray _srcB, OutputArray _dst, int flags, bool conjB) { Mat srcA = _srcA.getMat(), srcB = _srcB.getMat(); int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type(); int rows = srcA.rows, cols = srcA.cols; int j, k; CV_Assert( type == srcB.type() && srcA.size() == srcB.size() ); CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 ); _dst.create( srcA.rows, srcA.cols, type ); Mat dst = _dst.getMat(); bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 && srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous())); if( is_1d && !(flags & DFT_ROWS) ) cols = cols + rows - 1, rows = 1; int ncols = cols*cn; int j0 = cn == 1; int j1 = ncols - (cols % 2 == 0 && cn == 1); if( depth == CV_32F ) { const float* dataA = srcA.ptr<float>(); const float* dataB = srcB.ptr<float>(); float* dataC = dst.ptr<float>(); float eps = FLT_EPSILON; // prevent div0 problems size_t stepA = srcA.step/sizeof(dataA[0]); size_t stepB = srcB.step/sizeof(dataB[0]); size_t stepC = dst.step/sizeof(dataC[0]); if( !is_1d && cn == 1 ) { for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) { if( k == 1 ) dataA += cols - 1, dataB += cols - 1, dataC += cols - 1; dataC[0] = dataA[0] / (dataB[0] + eps); if( rows % 2 == 0 ) dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps); if( !conjB ) for( j = 1; j <= rows - 2; j += 2 ) { double denom = (double)dataB[j*stepB]*dataB[j*stepB] + (double)dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + (double)eps; double re = (double)dataA[j*stepA]*dataB[j*stepB] + (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] - (double)dataA[j*stepA]*dataB[(j+1)*stepB]; dataC[j*stepC] = (float)(re / denom); dataC[(j+1)*stepC] = (float)(im / denom); } else for( j = 1; j <= rows - 2; j += 2 ) { double denom = (double)dataB[j*stepB]*dataB[j*stepB] + (double)dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + (double)eps; double re = (double)dataA[j*stepA]*dataB[j*stepB] - (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] + (double)dataA[j*stepA]*dataB[(j+1)*stepB]; dataC[j*stepC] = (float)(re / denom); dataC[(j+1)*stepC] = (float)(im / denom); } if( k == 1 ) dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1; } } for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC ) { if( is_1d && cn == 1 ) { dataC[0] = dataA[0] / (dataB[0] + eps); if( cols % 2 == 0 ) dataC[j1] = dataA[j1] / (dataB[j1] + eps); } if( !conjB ) for( j = j0; j < j1; j += 2 ) { double denom = (double)(dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps); double re = (double)(dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1]); double im = (double)(dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1]); dataC[j] = (float)(re / denom); dataC[j+1] = (float)(im / denom); } else for( j = j0; j < j1; j += 2 ) { double denom = (double)(dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps); double re = (double)(dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1]); double im = (double)(dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1]); dataC[j] = (float)(re / denom); dataC[j+1] = (float)(im / denom); } } } else { const double* dataA = srcA.ptr<double>(); const double* dataB = srcB.ptr<double>(); double* dataC = dst.ptr<double>(); double eps = DBL_EPSILON; // prevent div0 problems size_t stepA = srcA.step/sizeof(dataA[0]); size_t stepB = srcB.step/sizeof(dataB[0]); size_t stepC = dst.step/sizeof(dataC[0]); if( !is_1d && cn == 1 ) { for( k = 0; k < (cols % 2 ? 1 : 2); k++ ) { if( k == 1 ) dataA += cols - 1, dataB += cols - 1, dataC += cols - 1; dataC[0] = dataA[0] / (dataB[0] + eps); if( rows % 2 == 0 ) dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA] / (dataB[(rows-1)*stepB] + eps); if( !conjB ) for( j = 1; j <= rows - 2; j += 2 ) { double denom = dataB[j*stepB]*dataB[j*stepB] + dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + eps; double re = dataA[j*stepA]*dataB[j*stepB] + dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; double im = dataA[(j+1)*stepA]*dataB[j*stepB] - dataA[j*stepA]*dataB[(j+1)*stepB]; dataC[j*stepC] = re / denom; dataC[(j+1)*stepC] = im / denom; } else for( j = 1; j <= rows - 2; j += 2 ) { double denom = dataB[j*stepB]*dataB[j*stepB] + dataB[(j+1)*stepB]*dataB[(j+1)*stepB] + eps; double re = dataA[j*stepA]*dataB[j*stepB] - dataA[(j+1)*stepA]*dataB[(j+1)*stepB]; double im = dataA[(j+1)*stepA]*dataB[j*stepB] + dataA[j*stepA]*dataB[(j+1)*stepB]; dataC[j*stepC] = re / denom; dataC[(j+1)*stepC] = im / denom; } if( k == 1 ) dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1; } } for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC ) { if( is_1d && cn == 1 ) { dataC[0] = dataA[0] / (dataB[0] + eps); if( cols % 2 == 0 ) dataC[j1] = dataA[j1] / (dataB[j1] + eps); } if( !conjB ) for( j = j0; j < j1; j += 2 ) { double denom = dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps; double re = dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1]; double im = dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1]; dataC[j] = re / denom; dataC[j+1] = im / denom; } else for( j = j0; j < j1; j += 2 ) { double denom = dataB[j]*dataB[j] + dataB[j+1]*dataB[j+1] + eps; double re = dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1]; double im = dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1]; dataC[j] = re / denom; dataC[j+1] = im / denom; } } } }
static bool ipp_norm(Mat &src, int normType, Mat &mask, double &result) { CV_INSTRUMENT_REGION_IPP(); #if IPP_VERSION_X100 >= 700 size_t total_size = src.total(); int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; if( (src.dims == 2 || (src.isContinuous() && mask.isContinuous())) && cols > 0 && (size_t)rows*cols == total_size ) { if( !mask.empty() ) { IppiSize sz = { cols, rows }; int type = src.type(); typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *); ippiMaskNormFuncC1 ippiNorm_C1MR = normType == NORM_INF ? (type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8u_C1MR : type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_32f_C1MR : 0) : normType == NORM_L1 ? (type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8u_C1MR : type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_32f_C1MR : 0) : normType == NORM_L2 || normType == NORM_L2SQR ? (type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8u_C1MR : type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_32f_C1MR : 0) : 0; if( ippiNorm_C1MR ) { Ipp64f norm; if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 ) { result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm); return true; } } typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *); ippiMaskNormFuncC3 ippiNorm_C3CMR = normType == NORM_INF ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR : type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR : 0) : normType == NORM_L1 ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR : type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR : 0) : normType == NORM_L2 || normType == NORM_L2SQR ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR : type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR : 0) : 0; if( ippiNorm_C3CMR ) { Ipp64f norm1, norm2, norm3; if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 && CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 && CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0) { Ipp64f norm = normType == NORM_INF ? std::max(std::max(norm1, norm2), norm3) : normType == NORM_L1 ? norm1 + norm2 + norm3 : normType == NORM_L2 || normType == NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) : 0; result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm); return true; } } } else { IppiSize sz = { cols*src.channels(), rows }; int type = src.depth(); typedef IppStatus (CV_STDCALL* ippiNormFuncHint)(const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); typedef IppStatus (CV_STDCALL* ippiNormFuncNoHint)(const void *, int, IppiSize, Ipp64f *); ippiNormFuncHint ippiNormHint = normType == NORM_L1 ? (type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L1_32f_C1R : 0) : normType == NORM_L2 || normType == NORM_L2SQR ? (type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L2_32f_C1R : 0) : 0; ippiNormFuncNoHint ippiNorm = normType == NORM_INF ? (type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_8u_C1R : type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16u_C1R : type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16s_C1R : type == CV_32FC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_32f_C1R : 0) : normType == NORM_L1 ? (type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_8u_C1R : type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16u_C1R : type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16s_C1R : 0) : normType == NORM_L2 || normType == NORM_L2SQR ? (type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_8u_C1R : type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16u_C1R : type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16s_C1R : 0) : 0; if( ippiNormHint || ippiNorm ) { Ipp64f norm; IppStatus ret = ippiNormHint ? CV_INSTRUMENT_FUN_IPP(ippiNormHint, src.ptr(), (int)src.step[0], sz, &norm, ippAlgHintAccurate) : CV_INSTRUMENT_FUN_IPP(ippiNorm, src.ptr(), (int)src.step[0], sz, &norm); if( ret >= 0 ) { result = (normType == NORM_L2SQR) ? norm * norm : norm; return true; } } } } #else CV_UNUSED(src); CV_UNUSED(normType); CV_UNUSED(mask); CV_UNUSED(result); #endif return false; }
void updateMotionHistory( InputArray _silhouette, InputOutputArray _mhi, double timestamp, double duration ) { CV_Assert( _silhouette.type() == CV_8UC1 && _mhi.type() == CV_32FC1 ); CV_Assert( _silhouette.sameSize(_mhi) ); float ts = (float)timestamp; float delbound = (float)(timestamp - duration); CV_OCL_RUN(_mhi.isUMat() && _mhi.dims() <= 2, ocl_updateMotionHistory(_silhouette, _mhi, ts, delbound)) Mat silh = _silhouette.getMat(), mhi = _mhi.getMat(); Size size = silh.size(); #if defined(HAVE_IPP) int silhstep = (int)silh.step, mhistep = (int)mhi.step; #endif if( silh.isContinuous() && mhi.isContinuous() ) { size.width *= size.height; size.height = 1; #if defined(HAVE_IPP) silhstep = (int)silh.total(); mhistep = (int)mhi.total() * sizeof(Ipp32f); #endif } #if defined(HAVE_IPP) IppStatus status = ippiUpdateMotionHistory_8u32f_C1IR((const Ipp8u *)silh.data, silhstep, (Ipp32f *)mhi.data, mhistep, ippiSize(size.width, size.height), (Ipp32f)timestamp, (Ipp32f)duration); if (status >= 0) return; #endif #if CV_SSE2 volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); #endif for(int y = 0; y < size.height; y++ ) { const uchar* silhData = silh.ptr<uchar>(y); float* mhiData = mhi.ptr<float>(y); int x = 0; #if CV_SSE2 if( useSIMD ) { __m128 ts4 = _mm_set1_ps(ts), db4 = _mm_set1_ps(delbound); for( ; x <= size.width - 8; x += 8 ) { __m128i z = _mm_setzero_si128(); __m128i s = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(silhData + x)), z); __m128 s0 = _mm_cvtepi32_ps(_mm_unpacklo_epi16(s, z)), s1 = _mm_cvtepi32_ps(_mm_unpackhi_epi16(s, z)); __m128 v0 = _mm_loadu_ps(mhiData + x), v1 = _mm_loadu_ps(mhiData + x + 4); __m128 fz = _mm_setzero_ps(); v0 = _mm_and_ps(v0, _mm_cmpge_ps(v0, db4)); v1 = _mm_and_ps(v1, _mm_cmpge_ps(v1, db4)); __m128 m0 = _mm_and_ps(_mm_xor_ps(v0, ts4), _mm_cmpneq_ps(s0, fz)); __m128 m1 = _mm_and_ps(_mm_xor_ps(v1, ts4), _mm_cmpneq_ps(s1, fz)); v0 = _mm_xor_ps(v0, m0); v1 = _mm_xor_ps(v1, m1); _mm_storeu_ps(mhiData + x, v0); _mm_storeu_ps(mhiData + x + 4, v1); } } #endif for( ; x < size.width; x++ ) { float val = mhiData[x]; val = silhData[x] ? ts : val < delbound ? 0 : val; mhiData[x] = val; } } }
void cv::filterSpeckles( Mat& img, uchar newVal, int maxSpeckleSize, uchar maxDiff, Mat& _buf) { int MaxD = 1024; int WinSz = 64; int bufSize0 = (MaxD + 2)*sizeof(int) + (img.rows+WinSz+2)*MaxD*sizeof(int) + (img.rows + WinSz + 2)*sizeof(int) + (img.rows+WinSz+2)*MaxD*(WinSz+1)*sizeof(uchar) + 256; int bufSize1 = (img.cols + 9 + 2) * sizeof(int) + 256; int bufSz = max(bufSize0 * 1, bufSize1 * 2); _buf.create(1, bufSz, CV_8U); CV_Assert( img.type() == CV_8U ); int width = img.cols, height = img.rows, npixels = width*height; size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar)); if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize ) _buf.create(1, bufSize, CV_8U); uchar* buf = _buf.data; int i, j, dstep = img.step/sizeof(uchar); int* labels = (int*)buf; buf += npixels*sizeof(labels[0]); Point2s* wbuf = (Point2s*)buf; buf += npixels*sizeof(wbuf[0]); uchar* rtype = (uchar*)buf; int curlabel = 0; // clear out label assignments memset(labels, 0, npixels*sizeof(labels[0])); for( i = 0; i < height; i++ ) { uchar* ds = img.ptr<uchar>(i); int* ls = labels + width*i; for( j = 0; j < width; j++ ) { if( ds[j] != newVal ) // not a bad disparity { if( ls[j] ) // has a label, check for bad label { if( rtype[ls[j]] ) // small region, zero out disparity ds[j] = (uchar)newVal; } // no label, assign and propagate else { Point2s* ws = wbuf; // initialize wavefront Point2s p((short)j, (short)i); // current pixel curlabel++; // next label int count = 0; // current region size ls[j] = curlabel; // wavefront propagation while( ws >= wbuf ) // wavefront not empty { count++; // put neighbors onto wavefront uchar* dpp = &img.at<uchar>(p.y, p.x); uchar dp = *dpp; int* lpp = labels + width*p.y + p.x; if( p.x < width-1 && !lpp[+1] && dpp[+1] != newVal && std::abs(dp - dpp[+1]) <= maxDiff ) { lpp[+1] = curlabel; *ws++ = Point2s(p.x+1, p.y); } if( p.x > 0 && !lpp[-1] && dpp[-1] != newVal && std::abs(dp - dpp[-1]) <= maxDiff ) { lpp[-1] = curlabel; *ws++ = Point2s(p.x-1, p.y); } if( p.y < height-1 && !lpp[+width] && dpp[+dstep] != newVal && std::abs(dp - dpp[+dstep]) <= maxDiff ) { lpp[+width] = curlabel; *ws++ = Point2s(p.x, p.y+1); } if( p.y > 0 && !lpp[-width] && dpp[-dstep] != newVal && std::abs(dp - dpp[-dstep]) <= maxDiff ) { lpp[-width] = curlabel; *ws++ = Point2s(p.x, p.y-1); } // pop most recent and propagate // NB: could try least recent, maybe better convergence p = *--ws; } // assign label type if( count <= maxSpeckleSize ) // speckle region { //printf("count = %d\n", count); rtype[ls[j]] = 1; // small region label ds[j] = (uchar)newVal; } else { //printf("count = %d\n", count); rtype[ls[j]] = 0; // large region label } } } } } }
TEST(dummy, dummy_test){ Mat mat(3, 7, CV_8UC1, Scalar::all(0)); Mat submat = mat(Rect(0, 0, 2, 3)); EXPECT_FALSE(submat.isContinuous()); }
void cv::gpu::LUT(const GpuMat& src, const Mat& lut, GpuMat& dst) { class LevelsInit { public: Npp32s pLevels[256]; const Npp32s* pLevels3[3]; int nValues3[3]; LevelsInit() { nValues3[0] = nValues3[1] = nValues3[2] = 256; for (int i = 0; i < 256; ++i) pLevels[i] = i; pLevels3[0] = pLevels3[1] = pLevels3[2] = pLevels; } }; static LevelsInit lvls; int cn = src.channels(); CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3); CV_Assert(lut.depth() == CV_8U && (lut.channels() == 1 || lut.channels() == cn) && lut.rows * lut.cols == 256 && lut.isContinuous()); dst.create(src.size(), CV_MAKETYPE(lut.depth(), cn)); NppiSize sz; sz.height = src.rows; sz.width = src.cols; Mat nppLut; lut.convertTo(nppLut, CV_32S); if (src.type() == CV_8UC1) { nppSafeCall( nppiLUT_Linear_8u_C1R(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, nppLut.ptr<Npp32s>(), lvls.pLevels, 256) ); } else { Mat nppLut3[3]; const Npp32s* pValues3[3]; if (nppLut.channels() == 1) pValues3[0] = pValues3[1] = pValues3[2] = nppLut.ptr<Npp32s>(); else { cv::split(nppLut, nppLut3); pValues3[0] = nppLut3[0].ptr<Npp32s>(); pValues3[1] = nppLut3[1].ptr<Npp32s>(); pValues3[2] = nppLut3[2].ptr<Npp32s>(); } nppSafeCall( nppiLUT_Linear_8u_C3R(src.ptr<Npp8u>(), src.step, dst.ptr<Npp8u>(), dst.step, sz, pValues3, lvls.pLevels3, lvls.nValues3) ); } }
//----------------------------------------------------------------------------- //https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0 void updateCellLife(const Mat& imgSrc, Mat& imgDst){ CV_Assert(imgSrc.type() == CV_32FC1); CV_Assert(imgDst.type() == CV_32FC1); CV_Assert(imgSrc.size() == imgDst.size()); CV_Assert(imgSrc.isContinuous()); CV_Assert(imgDst.isContinuous()); int width = imgSrc.cols; int height = imgSrc.rows; #ifdef _OPENMP #pragma omp parallel for #endif for (int y = 0; y < height; y++){ const float* src = imgSrc.ptr<float>(y); float* dst = imgDst.ptr<float>(y); for (int x = 0; x < width; x++){ int liveCell = 0; for (int dy = -1; dy <= 1; dy++){ for (int dx = -1; dx <= 1; dx++){ if (dx == 0 && dy == 0) continue;//自分は数えない int _x = x+dx; int _y = y+dy; #ifdef LIFE_BOUND_REPEAT _x = IMOD(_x , width ); _y = IMOD(_y , height); #else //境界 if (_x < 0)continue; if (_x >= width)continue; if (_y < 0)continue; if (_y >= height)continue; #endif // int idx = _y*width + _x; int idx = (_y-y)*width + _x; if (src[idx] != 0.0) liveCell++; } } // int idx = (y*width + x); int idx = (x); //誕生:死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代が誕生する。 if (src[idx] == 0.0 && liveCell == 3) dst[idx] = 1.0; //生存:生きているセルに隣接する生きたセルが2つか3つならば、次の世代でも生存する。 else if (src[idx] != 0.0 && (liveCell == 2 || liveCell == 3)) dst[idx] = 1.0; //過疎: 生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する。 else if (src[idx] != 0.0 && (liveCell <= 1)) dst[idx] = 0.0; //過密: 生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する。 else if (src[idx] != 0.0 && (liveCell >= 4)) dst[idx] = 0.0; //現状維持 else dst[idx] = src[idx]; } } }
static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat()) { _dst.create(_src.size(), _src.type()); int i, j, k, n = _dst.cols + _dst.rows - 1; Mat wave = _wave; double scale = (flags & DFT_SCALE) ? 1./n : 1.; size_t esz = _src.elemSize(); size_t srcstep = esz, dststep = esz; const uchar* src0 = _src.ptr(); uchar* dst0 = _dst.ptr(); CV_Assert( _src.cols + _src.rows - 1 == n ); if( wave.empty() ) wave = initDFTWave( n, (flags & DFT_INVERSE) != 0 ); const Complexd* w = wave.ptr<Complexd>(); if( !_src.isContinuous() ) srcstep = _src.step; if( !_dst.isContinuous() ) dststep = _dst.step; if( _src.type() == CV_32FC2 ) { for( i = 0; i < n; i++ ) { Complexf* dst = (Complexf*)(dst0 + i*dststep); Complexd sum(0,0); int delta = i; k = 0; for( j = 0; j < n; j++ ) { const Complexf* src = (const Complexf*)(src0 + j*srcstep); sum.re += src->re*w[k].re - src->im*w[k].im; sum.im += src->re*w[k].im + src->im*w[k].re; k += delta; k -= (k >= n ? n : 0); } dst->re = (float)(sum.re*scale); dst->im = (float)(sum.im*scale); } } else if( _src.type() == CV_64FC2 ) { for( i = 0; i < n; i++ ) { Complexd* dst = (Complexd*)(dst0 + i*dststep); Complexd sum(0,0); int delta = i; k = 0; for( j = 0; j < n; j++ ) { const Complexd* src = (const Complexd*)(src0 + j*srcstep); sum.re += src->re*w[k].re - src->im*w[k].im; sum.im += src->re*w[k].im + src->im*w[k].re; k += delta; k -= (k >= n ? n : 0); } dst->re = sum.re*scale; dst->im = sum.im*scale; } } else CV_Error(CV_StsUnsupportedFormat, ""); }
void calc_activ_func( Mat& sums, const Mat& w ) const { const double* bias = w.ptr<double>(w.rows-1); int i, j, n = sums.rows, cols = sums.cols; double scale = 0, scale2 = f_param2; switch( activ_func ) { case IDENTITY: scale = 1.; break; case SIGMOID_SYM: scale = -f_param1; break; case GAUSSIAN: scale = -f_param1*f_param1; break; default: ; } CV_Assert( sums.isContinuous() ); if( activ_func != GAUSSIAN ) { for( i = 0; i < n; i++ ) { double* data = sums.ptr<double>(i); for( j = 0; j < cols; j++ ) data[j] = (data[j] + bias[j])*scale; } if( activ_func == IDENTITY ) return; } else { for( i = 0; i < n; i++ ) { double* data = sums.ptr<double>(i); for( j = 0; j < cols; j++ ) { double t = data[j] + bias[j]; data[j] = t*t*scale; } } } exp( sums, sums ); if( sums.isContinuous() ) { cols *= n; n = 1; } switch( activ_func ) { case SIGMOID_SYM: for( i = 0; i < n; i++ ) { double* data = sums.ptr<double>(i); for( j = 0; j < cols; j++ ) { double t = scale2*(1. - data[j])/(1. + data[j]); data[j] = t; } } break; case GAUSSIAN: for( i = 0; i < n; i++ ) { double* data = sums.ptr<double>(i); for( j = 0; j < cols; j++ ) data[j] = scale2*data[j]; } break; default: ; } }
static void thresh_32f( const Mat& _src, Mat& _dst, float thresh, float maxval, int type ) { int i, j; Size roi = _src.size(); roi.width *= _src.channels(); const float* src = _src.ptr<float>(); float* dst = _dst.ptr<float>(); size_t src_step = _src.step/sizeof(src[0]); size_t dst_step = _dst.step/sizeof(dst[0]); #if CV_SSE2 volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE); #endif if( _src.isContinuous() && _dst.isContinuous() ) { roi.width *= roi.height; roi.height = 1; } #ifdef HAVE_TEGRA_OPTIMIZATION if (tegra::thresh_32f(_src, _dst, roi.width, roi.height, thresh, maxval, type)) return; #endif #if defined(HAVE_IPP) CV_IPP_CHECK() { IppiSize sz = { roi.width, roi.height }; switch( type ) { case THRESH_TRUNC: if (0 <= ippiThreshold_GT_32f_C1R(src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh)) { CV_IMPL_ADD(CV_IMPL_IPP); return; } setIppErrorStatus(); break; case THRESH_TOZERO: if (0 <= ippiThreshold_LTVal_32f_C1R(src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh+FLT_EPSILON, 0)) { CV_IMPL_ADD(CV_IMPL_IPP); return; } setIppErrorStatus(); break; case THRESH_TOZERO_INV: if (0 <= ippiThreshold_GTVal_32f_C1R(src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh, 0)) { CV_IMPL_ADD(CV_IMPL_IPP); return; } setIppErrorStatus(); break; } } #endif switch( type ) { case THRESH_BINARY: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128 thresh4 = _mm_set1_ps(thresh), maxval4 = _mm_set1_ps(maxval); for( ; j <= roi.width - 8; j += 8 ) { __m128 v0, v1; v0 = _mm_loadu_ps( src + j ); v1 = _mm_loadu_ps( src + j + 4 ); v0 = _mm_cmpgt_ps( v0, thresh4 ); v1 = _mm_cmpgt_ps( v1, thresh4 ); v0 = _mm_and_ps( v0, maxval4 ); v1 = _mm_and_ps( v1, maxval4 ); _mm_storeu_ps( dst + j, v0 ); _mm_storeu_ps( dst + j + 4, v1 ); } } #elif CV_NEON float32x4_t v_thresh = vdupq_n_f32(thresh); uint32x4_t v_maxval = vreinterpretq_u32_f32(vdupq_n_f32(maxval)); for( ; j <= roi.width - 4; j += 4 ) { float32x4_t v_src = vld1q_f32(src + j); uint32x4_t v_dst = vandq_u32(vcgtq_f32(v_src, v_thresh), v_maxval); vst1q_f32(dst + j, vreinterpretq_f32_u32(v_dst)); } #endif for( ; j < roi.width; j++ ) dst[j] = src[j] > thresh ? maxval : 0; } break; case THRESH_BINARY_INV: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128 thresh4 = _mm_set1_ps(thresh), maxval4 = _mm_set1_ps(maxval); for( ; j <= roi.width - 8; j += 8 ) { __m128 v0, v1; v0 = _mm_loadu_ps( src + j ); v1 = _mm_loadu_ps( src + j + 4 ); v0 = _mm_cmple_ps( v0, thresh4 ); v1 = _mm_cmple_ps( v1, thresh4 ); v0 = _mm_and_ps( v0, maxval4 ); v1 = _mm_and_ps( v1, maxval4 ); _mm_storeu_ps( dst + j, v0 ); _mm_storeu_ps( dst + j + 4, v1 ); } } #elif CV_NEON float32x4_t v_thresh = vdupq_n_f32(thresh); uint32x4_t v_maxval = vreinterpretq_u32_f32(vdupq_n_f32(maxval)); for( ; j <= roi.width - 4; j += 4 ) { float32x4_t v_src = vld1q_f32(src + j); uint32x4_t v_dst = vandq_u32(vcleq_f32(v_src, v_thresh), v_maxval); vst1q_f32(dst + j, vreinterpretq_f32_u32(v_dst)); } #endif for( ; j < roi.width; j++ ) dst[j] = src[j] <= thresh ? maxval : 0; } break; case THRESH_TRUNC: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128 thresh4 = _mm_set1_ps(thresh); for( ; j <= roi.width - 8; j += 8 ) { __m128 v0, v1; v0 = _mm_loadu_ps( src + j ); v1 = _mm_loadu_ps( src + j + 4 ); v0 = _mm_min_ps( v0, thresh4 ); v1 = _mm_min_ps( v1, thresh4 ); _mm_storeu_ps( dst + j, v0 ); _mm_storeu_ps( dst + j + 4, v1 ); } } #elif CV_NEON float32x4_t v_thresh = vdupq_n_f32(thresh); for( ; j <= roi.width - 4; j += 4 ) vst1q_f32(dst + j, vminq_f32(vld1q_f32(src + j), v_thresh)); #endif for( ; j < roi.width; j++ ) dst[j] = std::min(src[j], thresh); } break; case THRESH_TOZERO: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128 thresh4 = _mm_set1_ps(thresh); for( ; j <= roi.width - 8; j += 8 ) { __m128 v0, v1; v0 = _mm_loadu_ps( src + j ); v1 = _mm_loadu_ps( src + j + 4 ); v0 = _mm_and_ps(v0, _mm_cmpgt_ps(v0, thresh4)); v1 = _mm_and_ps(v1, _mm_cmpgt_ps(v1, thresh4)); _mm_storeu_ps( dst + j, v0 ); _mm_storeu_ps( dst + j + 4, v1 ); } } #elif CV_NEON float32x4_t v_thresh = vdupq_n_f32(thresh); for( ; j <= roi.width - 4; j += 4 ) { float32x4_t v_src = vld1q_f32(src + j); uint32x4_t v_dst = vandq_u32(vcgtq_f32(v_src, v_thresh), vreinterpretq_u32_f32(v_src)); vst1q_f32(dst + j, vreinterpretq_f32_u32(v_dst)); } #endif for( ; j < roi.width; j++ ) { float v = src[j]; dst[j] = v > thresh ? v : 0; } } break; case THRESH_TOZERO_INV: for( i = 0; i < roi.height; i++, src += src_step, dst += dst_step ) { j = 0; #if CV_SSE2 if( useSIMD ) { __m128 thresh4 = _mm_set1_ps(thresh); for( ; j <= roi.width - 8; j += 8 ) { __m128 v0, v1; v0 = _mm_loadu_ps( src + j ); v1 = _mm_loadu_ps( src + j + 4 ); v0 = _mm_and_ps(v0, _mm_cmple_ps(v0, thresh4)); v1 = _mm_and_ps(v1, _mm_cmple_ps(v1, thresh4)); _mm_storeu_ps( dst + j, v0 ); _mm_storeu_ps( dst + j + 4, v1 ); } } #elif CV_NEON float32x4_t v_thresh = vdupq_n_f32(thresh); for( ; j <= roi.width - 4; j += 4 ) { float32x4_t v_src = vld1q_f32(src + j); uint32x4_t v_dst = vandq_u32(vcleq_f32(v_src, v_thresh), vreinterpretq_u32_f32(v_src)); vst1q_f32(dst + j, vreinterpretq_f32_u32(v_dst)); } #endif for( ; j < roi.width; j++ ) { float v = src[j]; dst[j] = v <= thresh ? v : 0; } } break; default: return CV_Error( CV_StsBadArg, "" ); } }
// main routine int main(int argc, char* argv[]) { //%%%%%%%%%%%%%%%%%%%%%%%% init %%%%%%%%%%%%%%%%%%%%%%%% // read arguments if(argc<3) { cerr << "Usage: ComputeFeatures config.txt override(no(0)/yes(1))" << endl; exit(-1); } // read config file StructParam param; if(!param.loadConfigFeature(argv[1])) { cerr << "Could not parse " << argv[1] << endl; exit(-1); } // read test/anno data (uses same data structure) AnnotationData TestD; TestD.loadAnnoFile(param.test_file.c_str()); //if(atoi(argv[2])==2) //system(("rm " + param.feature_path + "/*.pgm").c_str()); // detect hypotheses on all images for(int i=0; i<TestD.AnnoData.size(); ++i) { // read image Mat originImg = imread((param.image_path+"/"+TestD.AnnoData[i].image_name).c_str()); if(originImg.empty()) { cerr << "Could not read image file " << param.image_path << "/" << TestD.AnnoData[i].image_name << endl; continue; } cout << system(("mkdir " + param.feature_path + "/" + TestD.AnnoData[i].image_name).c_str()); // extract features for(int k=0; k<param.scales.size(); ++k) { Features Feat; string fname(param.feature_path+"/"+TestD.AnnoData[i].image_name+"/"+TestD.AnnoData[i].image_name); if( atoi(argv[2])==1 || !Feat.loadFeatures( fname, param.scales[k]) ) { Mat scaledImg; resize(originImg, scaledImg, Size(int(originImg.cols * param.scales[k] + 0.5), int(originImg.rows * param.scales[k] + 0.5)) ); Feat.extractFeatureChannels(scaledImg); Feat.saveFeatures( fname, param.scales[k]); #if 0 // debug!!!! Features Feat2; namedWindow( "ShowF", CV_WINDOW_AUTOSIZE ); imshow( "ShowF", Feat.Channels[0] ); Feat2.loadFeatures( fname, param.scales[k]); namedWindow( "ShowF2", CV_WINDOW_AUTOSIZE ); imshow( "ShowF2", Feat2.Channels[0] ); cout << scaledImg.rows << " " << scaledImg.cols << " " << scaledImg.depth() << " " << scaledImg.channels() << " " << scaledImg.isContinuous() << endl; cout << Feat.Channels[0].rows << " " << Feat.Channels[0].cols << " " << Feat.Channels[0].depth() << " " << Feat.Channels[0].channels() << " " << Feat.Channels[0].isContinuous() << endl; cout << Feat2.Channels[0].rows << " " << Feat2.Channels[0].cols << " " << Feat2.Channels[0].depth() << " " << Feat2.Channels[0].channels() << " " << Feat.Channels[0].isContinuous() << endl; Mat diff(Size(scaledImg.cols,scaledImg.rows),CV_8UC1); cout << diff.rows << " " << diff.cols << " " << diff.depth() << " " << diff.channels() << " " << scaledImg.isContinuous() << endl; diff = Feat.Channels[0] - Feat2.Channels[0]; namedWindow( "ShowDiff", CV_WINDOW_AUTOSIZE ); imshow( "ShowDiff", diff ); waitKey(0); #endif } } } return 0; }
int CmColorQua::D_Quantize(CMat& img3f, Mat &idx1i, Mat &_color3f, Mat &_colorNum, double ratio, const int clrNums[3]) { float clrTmp[3] = {clrNums[0] - 0.0001f, clrNums[1] - 0.0001f, clrNums[2] - 0.0001f}; int w[3] = {clrNums[1] * clrNums[2], clrNums[2], 1}; CV_Assert(img3f.data != NULL); idx1i = Mat::zeros(img3f.size(), CV_32S); int rows = img3f.rows, cols = img3f.cols; if (img3f.isContinuous() && idx1i.isContinuous()){ cols *= rows; rows = 1; } // Build color pallet for (int y = 0; y < rows; y++) { const float* imgDataP = img3f.ptr<float>(y); int* idx = idx1i.ptr<int>(y); #pragma omp parallel for for (int x = 0; x < cols; x++){ const float* imgData = imgDataP + 3*x; idx[x] = (int)(imgData[0]*clrTmp[0])*w[0] + (int)(imgData[1]*clrTmp[1])*w[1] + (int)(imgData[2]*clrTmp[2]); } } map<int, int> pallet; for (int y = 0; y < rows; y++) { int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++) pallet[idx[x]] ++; } // Find significant colors int maxNum = 0; { int count = 0; vector<pair<int, int>> num; // (num, color) pairs in num num.reserve(pallet.size()); for (map<int, int>::iterator it = pallet.begin(); it != pallet.end(); it++) num.push_back(pair<int, int>(it->second, it->first)); // (color, num) pairs in pallet sort(num.begin(), num.end(), std::greater<pair<int, int>>()); maxNum = (int)num.size(); int maxDropNum = cvRound(rows * cols * (1-ratio)); for (int crnt = num[maxNum-1].first; crnt < maxDropNum && maxNum > 1; maxNum--) crnt += num[maxNum - 2].first; maxNum = min(maxNum, 256); // To avoid very rarely case if (maxNum <= 10) maxNum = min(10, (int)num.size()); pallet.clear(); for (int i = 0; i < maxNum; i++) pallet[num[i].second] = i; int numSZ = num.size(); vector<Vec3i> color3i(numSZ); #pragma omp parallel for for (int i = 0; i < numSZ; i++) { color3i[i][0] = num[i].second / w[0]; color3i[i][1] = num[i].second % w[0] / w[1]; color3i[i][2] = num[i].second % w[1]; } for (unsigned int i = maxNum; i < num.size(); i++) { int simIdx = 0, simVal = INT_MAX; #pragma omp parallel for for (int j = 0; j < maxNum; j++) { int d_ij = vecSqrDist(color3i[i], color3i[j]); if (d_ij < simVal) simVal = d_ij, simIdx = j; } pallet[num[i].second] = pallet[num[simIdx].second]; } } _color3f = Mat::zeros(1, maxNum, CV_32FC3); _colorNum = Mat::zeros(_color3f.size(), CV_32S); Vec3f* color = (Vec3f*)(_color3f.data); int* colorNum = (int*)(_colorNum.data); for (int y = 0; y < rows; y++) { const Vec3f* imgData = img3f.ptr<Vec3f>(y); int* idx = idx1i.ptr<int>(y); #pragma omp parallel for for (int x = 0; x < cols; x++) idx[x] = pallet[idx[x]]; for (int x = 0; x < cols; x++) { color[idx[x]] += imgData[x]; colorNum[idx[x]] ++; } } for (int i = 0; i < _color3f.cols; i++) color[i] /= colorNum[i]; return _color3f.cols; }
int main(int argc, char **argv) { CommandLineParser parser(argc, argv, keys); if (parser.has("help")) { parser.printMessage(); return 0; } String modelFile = parser.get<String>("model"); String imageFile = parser.get<String>("image"); if (!parser.check()) { parser.printErrors(); return 0; } String classNamesFile = parser.get<String>("c_names"); String resultFile = parser.get<String>("result"); //! [Read model and initialize network] dnn::Net net = dnn::readNetFromTorch(modelFile); //! [Prepare blob] Mat img = imread(imageFile), input; if (img.empty()) { std::cerr << "Can't read image from the file: " << imageFile << std::endl; exit(-1); } Size origSize = img.size(); Size inputImgSize = cv::Size(1024, 512); if (inputImgSize != origSize) resize(img, img, inputImgSize); //Resize image to input size Mat inputBlob = blobFromImage(img, 1./255); //Convert Mat to image batch //! [Prepare blob] //! [Set input blob] net.setInput(inputBlob, ""); //set the network input //! [Set input blob] TickMeter tm; String oBlob = net.getLayerNames().back(); if (!parser.get<String>("o_blob").empty()) { oBlob = parser.get<String>("o_blob"); } //! [Make forward pass] tm.start(); Mat result = net.forward(oBlob); tm.stop(); if (!resultFile.empty()) { CV_Assert(result.isContinuous()); ofstream fout(resultFile.c_str(), ios::out | ios::binary); fout.write((char*)result.data, result.total() * sizeof(float)); fout.close(); } std::cout << "Output blob: " << result.size[0] << " x " << result.size[1] << " x " << result.size[2] << " x " << result.size[3] << "\n"; std::cout << "Inference time, ms: " << tm.getTimeMilli() << std::endl; if (parser.has("show")) { std::vector<String> classNames; vector<cv::Vec3b> colors; if(!classNamesFile.empty()) { colors = readColors(classNamesFile, classNames); } Mat segm, legend; colorizeSegmentation(result, segm, legend, classNames, colors); Mat show; addWeighted(img, 0.1, segm, 0.9, 0.0, show); cv::resize(show, show, origSize, 0, 0, cv::INTER_NEAREST); imshow("Result", show); if(classNames.size()) imshow("Legend", legend); waitKey(); } return 0; } //main
// Filteres a face picture with 40 Gabor-filters, arranging the results into 3D-array-like // structure and runs 3D-LBP operation on them. Outputs an idetification histogram after // segmentation and concatenation in left-right, top-down order. // If step is 0 or 1 returns a debug picture in "face". ind = index per (freq*orientation)+rot void expression_recognizer::gaborLBPHistograms(Mat& face, Mat& hist, Mat& lut, int N, int step, int ind) { CV_Assert( face.depth() == CV_8U ); CV_Assert( face.channels() == 1 ); CV_Assert( lut.depth() == CV_8U ); CV_Assert( lut.channels() == 1 ); CV_Assert( lut.total() == 256 ); CV_Assert( lut.isContinuous() ); Mat tmppic = Mat( Size(64, 64), CV_64FC2); Mat holder = Mat( Size(64, 64), CV_64FC1); vector<Mat> planes; resize(face, face, Size(64,64)); //face = face.colRange(8,80);//.clone(); vector<Mat> doubleface; face.convertTo(face, CV_64FC2); int m = getOptimalDFTSize( face.size().height ); int n = getOptimalDFTSize( face.size().width ); copyMakeBorder(face, face, 0, m - face.size().height, 0, n - face.size().width, BORDER_CONSTANT, Scalar::all(0)); doubleface.clear(); doubleface.push_back(face); doubleface.push_back(face); merge( doubleface, face ); dft(face, face, DFT_COMPLEX_OUTPUT + DFT_SCALE, 0); vector<Mat> gaborCube(scale*orientation); vector<Mat> binaryGaborVolume; for (unsigned int freq=0;freq<scale;freq++) { for (unsigned int rot=0;rot<orientation;rot++) { unsigned int index = (freq*orientation)+rot; Mat tmp = gaborKernels[index]; mulSpectrums(face, tmp, tmppic, 0, false); idft(tmppic, tmppic, DFT_SCALE, 0); planes.clear(); split(tmppic, planes); Mat p0=planes[0]; Mat p1=planes[1]; magnitude(p0,p1,holder); //holder = holder.colRange(0, 64).rowRange(0,64); // From real and imaginary parts we can get the magnitude for identification // add 1px borders for later, store in gabor-cube copyMakeBorder(holder, holder,1, 1, 1, 1, BORDER_CONSTANT, Scalar::all(0)); gaborCube[index] = holder.clone(); } } if (step == 0) face = gaborCube[ind]; vector<Mat> LBP; Mat lbp = Mat(64,64,CV_8U); for (unsigned int freq=0;freq<scale;freq++) { for (unsigned int rot=0;rot<orientation;rot++) { unsigned int index = rot+(freq*orientation); Mat thiz = gaborCube[index]; uchar pix = 0; for (unsigned int y=1;y<thiz.size().height-1;y++) { for (unsigned int x=1;x<thiz.size().width-1;x++) { pix = 0; double center = thiz.at<double>(y,x); // indices 1,3,5 and 7 are normal closest neighbor LBP if (thiz.at<double>(y-1,x) >= center ) pix += powtable[1]; if (thiz.at<double>(y,x+1) >= center ) pix += powtable[3]; if (thiz.at<double>(y+1,x) >= center ) pix += powtable[5]; if (thiz.at<double>(y,x-1) >= center ) pix += powtable[7]; // orientation neighbors are indices 2 and 6 if (rot > 0) { Mat back = gaborCube[index-1]; if ( back.at<double>(y,x) >= center ) pix += powtable[2]; } if (rot < orientation-1) { Mat front = gaborCube[index+1]; if ( front.at<double>(y,x) >= center ) pix += powtable[6]; } //scale neighbors, indices 0,4 if (freq > 0 ) { Mat back = gaborCube[index-orientation]; if ( back.at<double>(y,x) >= center) pix += powtable[0]; } if (freq < scale-1) { Mat front = gaborCube[index+orientation]; if ( front.at<double>(y,x) >= center) pix += powtable[4]; } lbp.at<uchar>(y-1,x-1) = pix; } } // 59 uniform patterns if (N>0) LUT(lbp, lut, lbp); LBP.push_back(lbp.clone()); } } if (step == 1) face = LBP[ind]; int histSize[] = {256}; float range[] = {0, 256}; const float* histRange[] = {range}; int channels[]={0}; static double areaWeights[] = { 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,4,4,3,3,4,4,1, 1,4,4,3,3,4,4,1, 0,1,1,1,1,1,1,0, 0,1,2,2,2,2,1,0, 0,1,2,2,2,2,1,0, 0,0,1,1,1,1,0,0 }; static unsigned int xstep=8, ystep=8; static unsigned int xsize=8, ysize=8; for (unsigned int y = 0;y<ystep;y++) { for (unsigned int x = 0;x<xstep;x++) { Mat accuhist = Mat::zeros(256,1,CV_32F); unsigned int weight = areaWeights[x+(y*xsize)]; if (weight != 0) { for (unsigned int i=0;i<scale*orientation;i++) { Mat tempHist = Mat::zeros(256,1,CV_32F); lbp = LBP[i]; Mat roi = lbp.rowRange(y*ysize, (y+1)*ysize).colRange(x*xsize,(x+1)*xsize); calcHist(&roi, 1, 0, Mat(), tempHist, 1, histSize, histRange, true, false ); scaleAdd(tempHist, 1, accuhist, accuhist); } if (N>0) accuhist = accuhist.rowRange(0, N); // cut from 256 values per 8x8 area to 8 values per area //dump( accuhist ); hist.push_back(accuhist.clone()); //cuts the ID vector length even more } } } normalize( hist, hist, 0, 1, NORM_MINMAX, -1, noArray()); }
void cv::ogl::render(const ogl::Arrays& arr, InputArray indices, int mode, Scalar color) { #ifndef HAVE_OPENGL (void) arr; (void) indices; (void) mode; (void) color; throw_no_ogl(); #else if (!arr.empty() && !indices.empty()) { gl::Color3d(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0); arr.bind(); const int kind = indices.kind(); switch (kind) { case _InputArray::OPENGL_BUFFER : { ogl::Buffer buf = indices.getOGlBuffer(); const int depth = buf.depth(); CV_Assert( buf.channels() == 1 ); CV_Assert( depth <= CV_32S ); GLenum type; if (depth < CV_16U) type = gl::UNSIGNED_BYTE; else if (depth < CV_32S) type = gl::UNSIGNED_SHORT; else type = gl::UNSIGNED_INT; buf.bind(ogl::Buffer::ELEMENT_ARRAY_BUFFER); gl::DrawElements(mode, buf.size().area(), type, 0); ogl::Buffer::unbind(ogl::Buffer::ELEMENT_ARRAY_BUFFER); break; } default: { Mat mat = indices.getMat(); const int depth = mat.depth(); CV_Assert( mat.channels() == 1 ); CV_Assert( depth <= CV_32S ); CV_Assert( mat.isContinuous() ); GLenum type; if (depth < CV_16U) type = gl::UNSIGNED_BYTE; else if (depth < CV_32S) type = gl::UNSIGNED_SHORT; else type = gl::UNSIGNED_INT; ogl::Buffer::unbind(ogl::Buffer::ELEMENT_ARRAY_BUFFER); gl::DrawElements(mode, mat.size().area(), type, mat.data); } } } #endif }
inline Size getContinuousSize( const Mat& m1, int widthScale=1 ) { return m1.isContinuous() ? Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); }
int CMagicCabsineSplitData_GraphBase::Quantize(const Mat& img3f, Mat &idx1i, Mat &_color3f, Mat &_colorNum, double ratio) { static const int clrNums[3] = {12, 12, 12}; static const float clrTmp[3] = {clrNums[0] - 0.0001f, clrNums[1] - 0.0001f, clrNums[2] - 0.0001f}; static const int w[3] = {clrNums[1] * clrNums[2], clrNums[2], 1}; CV_Assert(img3f.data != NULL); idx1i = Mat::zeros(img3f.size(), CV_32S); int rows = img3f.rows, cols = img3f.cols; if (img3f.isContinuous() && idx1i.isContinuous()) { cols *= rows; rows = 1; } // Build color pallet map<int, int> pallet; for (int y = 0; y < rows; y++) { const float* imgData = img3f.ptr<float>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++, imgData += 3) { idx[x] = (int)(imgData[0]*clrTmp[0])*w[0] + (int)(imgData[1]*clrTmp[1])*w[1] + (int)(imgData[2]*clrTmp[2]); pallet[idx[x]] ++; } } // Fine significant colors int maxNum = 0; { int count = 0; vector<pair<int, int>> num; // (num, color) pairs in num num.reserve(pallet.size()); for (map<int, int>::iterator it = pallet.begin(); it != pallet.end(); it++) num.push_back(pair<int, int>(it->second, it->first)); // (color, num) pairs in pallet sort(num.begin(), num.end(), std::greater<pair<int, int>>()); maxNum = (int)num.size(); int maxDropNum = cvRound(rows * cols * (1-ratio)); for (int crnt = num[maxNum-1].first; crnt < maxDropNum && maxNum > 1; maxNum--) crnt += num[maxNum - 2].first; maxNum = min(maxNum, 256); // To avoid very rarely case if (maxNum < 10) maxNum = min((int)pallet.size(), 100); pallet.clear(); for (int i = 0; i < maxNum; i++) pallet[num[i].second] = i; vector<Vec3i> color3i(num.size()); for (unsigned int i = 0; i < num.size(); i++) { color3i[i][0] = num[i].second / w[0]; color3i[i][1] = num[i].second % w[0] / w[1]; color3i[i][2] = num[i].second % w[1]; } for (unsigned int i = maxNum; i < num.size(); i++) { int simIdx = 0, simVal = INT_MAX; for (int j = 0; j < maxNum; j++) { int d_ij = vecSqrDist3(color3i[i], color3i[j]); if (d_ij < simVal) simVal = d_ij, simIdx = j; } pallet[num[i].second] = pallet[num[simIdx].second]; } } _color3f = Mat::zeros(1, maxNum, CV_32FC3); _colorNum = Mat::zeros(_color3f.size(), CV_32S); Vec3f* color = (Vec3f*)(_color3f.data); int* colorNum = (int*)(_colorNum.data); for (int y = 0; y < rows; y++) { const Vec3f* imgData = img3f.ptr<Vec3f>(y); int* idx = idx1i.ptr<int>(y); for (int x = 0; x < cols; x++) { int temp=idx[x]; //cout<<idx[x]<<" "; idx[x] = pallet[temp]; Vec3f tmpVec3f=imgData[x]; temp=idx[x]; //cout<<idx[x]<<" "; color[temp] += tmpVec3f; colorNum[temp] ++; } } //把_color3f 和 color 和colornum全部打到文件里,就知道是什么了 for (int i = 0; i < _color3f.cols; i++) { color[i] /= colorNum[i]; cout<<color[i].val[0]<<" "<<color[i].val[1]<<" "<<color[i].val[2]<<" "<<colorNum[i]<<endl; } cout<<_color3f.cols<<endl; return _color3f.cols; }
void cv::ogl::Texture2D::copyFrom(InputArray arr, bool autoRelease) { #ifndef HAVE_OPENGL (void) arr; (void) autoRelease; throw_no_ogl(); #else const int kind = arr.kind(); const Size asize = arr.size(); const int atype = arr.type(); const int depth = CV_MAT_DEPTH(atype); const int cn = CV_MAT_CN(atype); CV_Assert( depth <= CV_32F ); CV_Assert( cn == 1 || cn == 3 || cn == 4 ); const Format internalFormats[] = { NONE, DEPTH_COMPONENT, NONE, RGB, RGBA }; const GLenum srcFormats[] = { 0, gl::DEPTH_COMPONENT, 0, gl::BGR, gl::BGRA }; create(asize, internalFormats[cn], autoRelease); switch(kind) { case _InputArray::OPENGL_BUFFER: { ogl::Buffer buf = arr.getOGlBuffer(); buf.bind(ogl::Buffer::PIXEL_UNPACK_BUFFER); impl_->copyFrom(asize.width, asize.height, srcFormats[cn], gl_types[depth], 0); ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); break; } case _InputArray::GPU_MAT: { #ifndef HAVE_CUDA throw_no_cuda(); #else GpuMat dmat = arr.getGpuMat(); ogl::Buffer buf(dmat, ogl::Buffer::PIXEL_UNPACK_BUFFER); buf.bind(ogl::Buffer::PIXEL_UNPACK_BUFFER); impl_->copyFrom(asize.width, asize.height, srcFormats[cn], gl_types[depth], 0); ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); #endif break; } default: { Mat mat = arr.getMat(); CV_Assert( mat.isContinuous() ); ogl::Buffer::unbind(ogl::Buffer::PIXEL_UNPACK_BUFFER); impl_->copyFrom(asize.width, asize.height, srcFormats[cn], gl_types[depth], mat.data); } } #endif }
void calcMotionGradient( InputArray _mhi, OutputArray _mask, OutputArray _orientation, double delta1, double delta2, int aperture_size ) { static int runcase = 0; runcase++; Mat mhi = _mhi.getMat(); Size size = mhi.size(); _mask.create(size, CV_8U); _orientation.create(size, CV_32F); Mat mask = _mask.getMat(); Mat orient = _orientation.getMat(); if( aperture_size < 3 || aperture_size > 7 || (aperture_size & 1) == 0 ) CV_Error( Error::StsOutOfRange, "aperture_size must be 3, 5 or 7" ); if( delta1 <= 0 || delta2 <= 0 ) CV_Error( Error::StsOutOfRange, "both delta's must be positive" ); if( mhi.type() != CV_32FC1 ) CV_Error( Error::StsUnsupportedFormat, "MHI must be single-channel floating-point images" ); if( orient.data == mhi.data ) { _orientation.release(); _orientation.create(size, CV_32F); orient = _orientation.getMat(); } if( delta1 > delta2 ) std::swap(delta1, delta2); float gradient_epsilon = 1e-4f * aperture_size * aperture_size; float min_delta = (float)delta1; float max_delta = (float)delta2; Mat dX_min, dY_max; // calc Dx and Dy Sobel( mhi, dX_min, CV_32F, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE ); Sobel( mhi, dY_max, CV_32F, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE ); int x, y; if( mhi.isContinuous() && orient.isContinuous() && mask.isContinuous() ) { size.width *= size.height; size.height = 1; } // calc gradient for( y = 0; y < size.height; y++ ) { const float* dX_min_row = dX_min.ptr<float>(y); const float* dY_max_row = dY_max.ptr<float>(y); float* orient_row = orient.ptr<float>(y); uchar* mask_row = mask.ptr<uchar>(y); hal::fastAtan2(dY_max_row, dX_min_row, orient_row, size.width, true); // make orientation zero where the gradient is very small for( x = 0; x < size.width; x++ ) { float dY = dY_max_row[x]; float dX = dX_min_row[x]; if( std::abs(dX) < gradient_epsilon && std::abs(dY) < gradient_epsilon ) { mask_row[x] = (uchar)0; orient_row[x] = 0.f; } else mask_row[x] = (uchar)1; } } erode( mhi, dX_min, noArray(), Point(-1,-1), (aperture_size-1)/2, BORDER_REPLICATE ); dilate( mhi, dY_max, noArray(), Point(-1,-1), (aperture_size-1)/2, BORDER_REPLICATE ); // mask off pixels which have little motion difference in their neighborhood for( y = 0; y < size.height; y++ ) { const float* dX_min_row = dX_min.ptr<float>(y); const float* dY_max_row = dY_max.ptr<float>(y); float* orient_row = orient.ptr<float>(y); uchar* mask_row = mask.ptr<uchar>(y); for( x = 0; x < size.width; x++ ) { float d0 = dY_max_row[x] - dX_min_row[x]; if( mask_row[x] == 0 || d0 < min_delta || max_delta < d0 ) { mask_row[x] = (uchar)0; orient_row[x] = 0.f; } } } }