void cvCLAdaptEqualize(const CvArr* srcarr, CvArr* dstarr, unsigned int xdivs, unsigned int ydivs, unsigned int bins, float limit, int range) { double min_val, max_val; unsigned char min, max; int type; IplImage sstub, *src = cvGetImage(srcarr, &sstub); IplImage dstub, *dst = cvGetImage(dstarr, &dstub); if ((src == NULL) || (dst == NULL)) CV_ERROR( CV_StsUnsupportedFormat, "NULL value passed as image to function" ); CV_CALL( type = cvGetElemType( src )); if( type != CV_8UC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" ); CV_CALL( type = cvGetElemType( src )); if( type != CV_8UC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" ); //if( !CV_ARE_SIZES_EQ( src, dst )) // Modified by Shervin Emami, 17Nov2010. if (src->width != dst->width || src->height != dst->height) CV_ERROR( CV_StsUnmatchedSizes, "src and dst images must be equal sizes" ); if (((xdivs < 2) || (xdivs > 16)) || ((ydivs < 2) || (ydivs > 16))) CV_ERROR( CV_StsBadFlag, "xdivs and ydivs must in range (MIN=2 MAX = 16)" ); if ((bins < 2) || (bins > 256)) CV_ERROR( CV_StsBadFlag, "bins must in range (MIN=2 MAX = 256)" ); // copy src to dst for in-place CLAHE. cvCopy(src, dst); // If the dimensions of the image are not a multiple of the xdivs and ydivs, then enlarge the image to be a correct size and then shrink the image. // Also make sure the image is aligned to 8 pixels width, so that OpenCV won't add extra padding to the image. // Added by Shervin Emami, 17Nov2010. int enlarged = 0; int origW = dst->width; int origH = dst->height; IplImage *tmpDst = 0; if ((dst->width & (8-1)) || (dst->height & (8-1)) || (dst->width % xdivs) || (dst->height % ydivs)) { int newW = ((dst->width + 8-1) & -8); // Align to 8 pixels, so that widthStep hopefully equals width. newW = ((newW + xdivs-1) & -xdivs); // Also align for CLAHE. int newH = ((dst->height + ydivs-1) & -ydivs); //std::cout << "w=" << dst->width << ", h=" << dst->height << ". new w = " << newW << ", h = " << newH << std::endl; IplImage *enlargedDst = cvCreateImage(cvSize(newW, newH), dst->depth, dst->nChannels); cvResize(dst, enlargedDst, CV_INTER_CUBIC); //cvReleaseImage(&dst); tmpDst = dst; dst = enlargedDst; // Use the enlarged image instead of the original dst image. enlarged = 1; // signal that we need to shrink later! } // Check if OpenCV adds padding bytes on each row. Added by Shervin Emami, 17Nov2010. if (dst->width != dst->widthStep) CV_ERROR( CV_StsBadFlag, "dst->widthStep should be the same as dst->width. The IplImage has padding, so use a larger image." ); // check number of xdivs and ydivs is a multiple of image dimensions if (dst->width % xdivs) CV_ERROR( CV_StsBadFlag, "xdiv must be an integer multiple of image width " ); if (dst->height % ydivs) CV_ERROR( CV_StsBadFlag, "ydiv must be an integer multiple of image height " ); // get the min and max values of the image if (range == CV_CLAHE_RANGE_INPUT) { cvMinMaxLoc(dst, &min_val, &max_val); min = (unsigned char) min_val; max = (unsigned char) max_val; } else { min = 0; max = 255; } // call CLHAHE for in-place CLAHE //int rcode = CLAHE((kz_pixel_t*) (dst->imageData), (unsigned int) dst->width, (unsigned int) dst->height, (kz_pixel_t) min, (kz_pixel_t) max, (unsigned int) xdivs, (unsigned int) ydivs, (unsigned int) bins, (float) limit); //printf("RCODE %i\n", rcode); // If the dst image was enlarged to fit the alignment, then shrink it back now. // Added by Shervin Emami, 17Nov2010. if (enlarged) { //std::cout << "w=" << dst->width << ", h=" << dst->height << ". orig w=" << origW << ", h=" << origH << std::endl; cvResize(dst, tmpDst, CV_INTER_CUBIC); // Shrink the enlarged image back into the original dst image. cvReleaseImage(&dst); // Free the enlarged image. } }
TiXmlElement* FileFormatUtils::createXMLMatrix(const char* element_name, const CvMat *matrix) { if (!matrix) return NULL; TiXmlElement* xml_matrix = new TiXmlElement(element_name); int precision; if (cvGetElemType(matrix) == CV_32F) { xml_matrix->SetAttribute("type", "CV_32F"); precision = std::numeric_limits<float>::digits10 + 2; } else if (cvGetElemType(matrix) == CV_64F) { xml_matrix->SetAttribute("type", "CV_64F"); precision = std::numeric_limits<double>::digits10 + 2; } else { delete xml_matrix; return NULL; } xml_matrix->SetAttribute("rows", matrix->rows); xml_matrix->SetAttribute("cols", matrix->cols); for (int r = 0; r < matrix->rows; ++r) { for (int c = 0; c < matrix->cols; ++c) { TiXmlElement *xml_data = new TiXmlElement("data"); xml_matrix->LinkEndChild(xml_data); std::stringstream ss; ss.precision(precision); ss<<cvGetReal2D(matrix, r, c); xml_data->LinkEndChild(new TiXmlText(ss.str().c_str())); } } return xml_matrix; }
CVAPI(void) cvShowImageEx(const char * id, const CvArr * arr, const int cm) { CvMat * src, src_stub; double minval, maxval, maxdiff; CvPoint minloc, maxloc; int type = cvGetElemType(arr); CvMat * disp, * src_scaled; int i, j; if (!CV_IS_MAT(arr)) src = cvGetMat(arr, &src_stub); else{ src = (CvMat*)arr; } src = cvCloneMat(src); if ( (src->rows<60) || (src->rows<60) ) { CvMat * orig = cvCloneMat(src); int scale=60./MIN(orig->rows, orig->cols); cvReleaseMat(&src); src = cvCreateMat(orig->rows*scale, orig->cols*scale, CV_MAT_TYPE(orig->type)); int m,n; if (CV_MAT_TYPE(src->type)==CV_64F){ for (m=0;m<orig->rows;m++) { for (n=0;n<orig->cols;n++) { for (i=0;i<scale;i++) { for (j=0;j<scale;j++) { CV_MAT_ELEM(*src, double, m*scale+i, n*scale+j) = CV_MAT_ELEM(*orig, double, m, n); } } } } }else if (CV_MAT_TYPE(src->type)==CV_32F){
/* * call-seq: * sub(val[,mask]) * * Return new CvScalar if <i>val</i> is CvScalar or compatible object. * self[I] - val[I] * Or return new CvMat if <i>val</i> is CvMat or subclass. */ VALUE rb_sub(int argc, VALUE *argv, VALUE self) { VALUE val, mask; rb_scan_args(argc, argv, "11", &val, &mask); if (rb_obj_is_kind_of(val, cCvMat::rb_class())) { CvArr *val_ptr = CVARR(val); VALUE dest = Qnil; try { dest = cCvMat::new_object(cvGetSize(val_ptr), cvGetElemType(val_ptr)); cvSubRS(val_ptr, *CVSCALAR(self), CVARR(dest), MASK(mask)); } catch (cv::Exception& e) { raise_cverror(e); } return dest; } else { CvScalar *src = CVSCALAR(self); CvScalar scl = VALUE_TO_CVSCALAR(val); return new_object(cvScalar(src->val[0] - scl.val[0], src->val[1] - scl.val[1], src->val[2] - scl.val[2], src->val[3] - scl.val[3])); } }
void cvPolyLineAA( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed, double color, int scale ) { cvPolyLine( img, pts, npts, contours, is_closed, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale ); }
// Rearrange the quadrants of Fourier image so that the origin is at // the image center // src & dst arrays of equal size & type void cvShiftDFT(CvArr *src_arr, CvArr *dst_arr ) { CvMat *tmp = NULL; CvMat q1stub, q2stub; CvMat q3stub, q4stub; CvMat d1stub, d2stub; CvMat d3stub, d4stub; CvMat *q1, *q2, *q3, *q4; CvMat *d1, *d2, *d3, *d4; CvSize size = cvGetSize(src_arr); CvSize dst_size = cvGetSize(dst_arr); int cx, cy; if(dst_size.width != size.width || dst_size.height != size.height){ cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ ); } if(src_arr==dst_arr){ tmp = rb_cvCreateMat(size.height/2, size.width/2, cvGetElemType(src_arr)); } cx = size.width/2; cy = size.height/2; // image center q1 = cvGetSubRect( src_arr, &q1stub, cvRect(0,0,cx, cy) ); q2 = cvGetSubRect( src_arr, &q2stub, cvRect(cx,0,cx,cy) ); q3 = cvGetSubRect( src_arr, &q3stub, cvRect(cx,cy,cx,cy) ); q4 = cvGetSubRect( src_arr, &q4stub, cvRect(0,cy,cx,cy) ); d1 = cvGetSubRect( src_arr, &d1stub, cvRect(0,0,cx,cy) ); d2 = cvGetSubRect( src_arr, &d2stub, cvRect(cx,0,cx,cy) ); d3 = cvGetSubRect( src_arr, &d3stub, cvRect(cx,cy,cx,cy) ); d4 = cvGetSubRect( src_arr, &d4stub, cvRect(0,cy,cx,cy) ); if(src_arr!=dst_arr){ if( !CV_ARE_TYPES_EQ( q1, d1 )){ cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ ); } cvCopy(q3, d1, 0); cvCopy(q4, d2, 0); cvCopy(q1, d3, 0); cvCopy(q2, d4, 0); } else{ cvCopy(q3, tmp, 0); cvCopy(q1, q3, 0); cvCopy(tmp, q1, 0); cvCopy(q4, tmp, 0); cvCopy(q2, q4, 0); cvCopy(tmp, q2, 0); } if (tmp != NULL) { cvReleaseMat(&tmp); } }
void cvEllipseAA( CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, double color, int scale) { cvEllipse( img, center, axes, angle, start_angle, end_angle, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale ); }
void test(CvMat* t) { //获取矩阵的数据类型 int type = cvGetElemType(t); CvHistogram //获取矩阵的维度信息 int size[10]; int dims = cvGetDims(t, size); int x = cvGetDimSize(t, 0); int y = cvGetDimSize(t, 1); }
double CxCore_MulSpectrumsTest::get_success_error_level( int test_case_idx, int i, int j ) { CV_UNUSED(test_case_idx); CV_Assert(i == OUTPUT); CV_Assert(j == 0); int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j])); CV_Assert(elem_depth == CV_32F || elem_depth == CV_64F); element_wise_relative_error = false; double maxInputValue = 1000; // ArrayTest::get_minmax_bounds double err = 8 * maxInputValue; // result = A*B + C*D return (elem_depth == CV_32F ? FLT_EPSILON : DBL_EPSILON) * err; }
void CvArrTest::fill_array( int /*test_case_idx*/, int i, int j, CvMat* arr ) { if( i == REF_INPUT_OUTPUT ) cvTsCopy( &test_mat[INPUT_OUTPUT][j], arr, 0 ); else if( i == INPUT || i == INPUT_OUTPUT || i == MASK ) { int type = cvGetElemType( arr ); CvScalar low, high; get_minmax_bounds( i, j, type, &low, &high ); cvTsRandUni( ts->get_rng(), arr, low, high ); } }
/* * call-seq: * sub(val[,mask]) * * Return new CvScalar if <i>val</i> is CvScalar or compatible object. * self[I] - val[I] * Or return new CvMat if <i>val</i> is CvMat or subclass. */ VALUE rb_sub(int argc, VALUE *argv, VALUE self) { VALUE val, mask; rb_scan_args(argc, argv, "11", &val, &mask); if(rb_obj_is_kind_of(val, cCvMat::rb_class())){ VALUE dest = cCvMat::new_object(cvGetSize(CVARR(val)), cvGetElemType(CVARR(val))); cvSubRS(CVARR(val), *CVSCALAR(self), CVARR(dest), MASK(mask)); return dest; }else{ CvScalar *src = CVSCALAR(self), scl = VALUE_TO_CVSCALAR(val); return new_object(cvScalar(src->val[0] - scl.val[0], src->val[1] - scl.val[1], src->val[2] - scl.val[2], src->val[3] - scl.val[3])); } }
////////////////////////compute the meshgrid arrays needed for LPF////////////////////////////////////////////////// // CDM compute meshgrid frequency matrices (ok!) // see Gonzalez Digital image processing using matlab page93 function dftuv void CLightSet::CDM(int M,int N,CvMat *mat) { int width = mat->rows; int height = mat->cols; if (M != width && N != height) { //cout<<"ERROR! THE SIZE DOES NOT MATCH WITH MAT"<<endl; return; } if (cvGetElemType(mat) < CV_32F) { //cout<<"ERROR! THE TYPE DOES NOT MATCH WITH MAT"<<endl; return; } CvMat *U,*V; U = cvCreateMat(M,N,CV_32FC1); V = cvCreateMat(M,N,CV_32FC1); for (int u = 0; u < M; ++u) for (int v =0 ;v < N; ++v) { float tm1,tm2; tm1 = (float)((u > cvRound(M/2))?u-M:u); tm2 = (float)((v > cvRound(N/2))?v-N:v); *( (float *)CV_MAT_ELEM_PTR(*U,u,v) ) = tm1; *( (float *)CV_MAT_ELEM_PTR(*V,u,v) ) = tm2; } for ( int u = 0; u < M; ++u) for (int v =0 ;v < N; ++v) { float t1,t2; t1 = CV_MAT_ELEM(*U,float,u,v); t2 = CV_MAT_ELEM(*V,float,u,v); *( (float *)CV_MAT_ELEM_PTR(*mat,u,v) ) = sqrt(t1*t1 + t2*t2); } }
static bool check_size_type(const CvMat* src, const char* name) { if(src->rows != src->cols) { fprintf(stderr, "MT_Cholesky Error: %s must be a square matrix.\n", name); return false; } if(cvGetElemType(src) != CV_64FC1) { fprintf(stderr, "MT_Cholesky Error: %s must be a single-channel " "matrix of doubles.\n", name); return false; } return true; }
void MT_CVQuadraticMul(const CvMat* X, const CvMat* W, CvMat* dst, bool transpose_X, CvMat* tmp_prod) { bool own_prod = (tmp_prod == NULL); if(own_prod) { tmp_prod = cvCreateMat(W->rows, X->cols, cvGetElemType(X)); } cvGEMM(W, X, 1.0, NULL, 1.0, tmp_prod, transpose_X ? CV_GEMM_B_T : 0); cvGEMM(X, tmp_prod, 1.0, NULL, 1.0, dst, transpose_X ? 0 : CV_GEMM_A_T); if(own_prod) { cvReleaseMat(&tmp_prod); } }
bool FileFormatUtils::parseXMLMatrix(const TiXmlElement *xml_matrix, CvMat *matrix) { if (!xml_matrix || !matrix) return false; int type, rows, cols; if (!decodeXMLMatrix(xml_matrix, type, rows, cols)) return false; if (type != cvGetElemType(matrix)) return false; if (rows != matrix->rows) return false; if (cols != matrix->cols) return false; const TiXmlElement *xml_data = xml_matrix->FirstChildElement("data"); for (int r = 0; r < matrix->rows; ++r) { for (int c = 0; c < matrix->cols; ++c) { if (!xml_data) return false; double value = atof(xml_data->GetText()); cvSetReal2D(matrix, r, c, value); xml_data = (const TiXmlElement *) xml_data->NextSibling("data"); } } return true; }
bool CvCalibFilter::FindEtalon( CvMat** mats ) { bool result = true; if( !mats || etalonPointCount == 0 ) { assert(0); result = false; } if( result ) { int i, tempPointCount0 = etalonPointCount*2; for( i = 0; i < cameraCount; i++ ) { if( !latestPoints[i] ) latestPoints[i] = (CvPoint2D32f*) cvAlloc( tempPointCount0*2*sizeof(latestPoints[0])); } for( i = 0; i < cameraCount; i++ ) { CvSize size; int tempPointCount = tempPointCount0; bool found = false; if( !CV_IS_MAT(mats[i]) && !CV_IS_IMAGE(mats[i])) { assert(0); break; } size = cvGetSize(mats[i]); if( size.width != imgSize.width || size.height != imgSize.height ) { imgSize = size; } if( !grayImg || grayImg->width != imgSize.width || grayImg->height != imgSize.height ) { cvReleaseMat( &grayImg ); cvReleaseMat( &tempImg ); grayImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 ); tempImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 ); } if( !storage ) storage = cvCreateMemStorage(); switch( etalonType ) { case CV_CALIB_ETALON_CHESSBOARD: if( CV_MAT_CN(cvGetElemType(mats[i])) == 1 ) cvCopy( mats[i], grayImg ); else cvCvtColor( mats[i], grayImg, CV_BGR2GRAY ); found = cvFindChessBoardCornerGuesses( grayImg, tempImg, storage, cvSize( cvRound(etalonParams[0]), cvRound(etalonParams[1])), latestPoints[i], &tempPointCount ) != 0; if( found ) cvFindCornerSubPix( grayImg, latestPoints[i], tempPointCount, cvSize(5,5), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1)); break; default: assert(0); result = false; break; } latestCounts[i] = found ? tempPointCount : -tempPointCount; result = result && found; } } if( storage ) cvClearMemStorage( storage ); return result; }
double ArrayTest::get_success_error_level( int /*test_case_idx*/, int i, int j ) { int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j])); assert( i == OUTPUT || i == INPUT_OUTPUT ); return elem_depth < CV_32F ? 0 : elem_depth == CV_32F ? FLT_EPSILON*100: DBL_EPSILON*5000; }
/* old drawing functions */ void cvLineAA( CvArr* img, CvPoint pt1, CvPoint pt2, double color, int scale) { cvLine( img, pt1, pt2, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale ); }
void cvCircleAA( CvArr* img, CvPoint center, int radius, double color, int scale) { cvCircle( img, center, radius, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale ); }
/** * Euclidean distance transform of a binary image, * Computation performed upon 'short' values * * @param src IN: positive pixels are treated as background * @param distxArr OUT: * @param distyArr OUT: */ void cvCalcEuclideanDistance( const CvArr * src, // positive pixels are treated as background CvArr * distxArr, CvArr * distyArr) { CV_FUNCNAME("cvEuclideanDistance"); int x, y, i; int offset_u, offset_ur, offset_r, offset_rd, offset_d, offset_dl, offset_l, offset_lu; double olddist2, newdist2, newdistx, newdisty; int changed; __BEGIN__; // CV_ASSERT(cvGetElemType(src)==CV_16S); // CV_ASSERT(cvGetElemType(distxArr)==CV_16S); // CV_ASSERT(cvGetElemType(distyArr)==CV_16S); CvMat srcHeader, distHeaderX, distHeaderY; CvMat * srcImage = cvGetMat(src, &srcHeader); CvMat * distImageX = cvGetMat(distxArr, &distHeaderX); CvMat * distImageY = cvGetMat(distyArr, &distHeaderY); CvMat * srcImage2 = cvCreateMat(srcImage->rows, srcImage->cols, CV_16S); CvMat * distImageX2 = cvCreateMat(srcImage->rows, srcImage->cols, CV_16S); CvMat * distImageY2 = cvCreateMat(srcImage->rows, srcImage->cols, CV_16S); if (cvGetElemType(src)!=CV_16S) cvConvert(srcImage, srcImage2); else cvCopy(srcImage, srcImage2); CvMat distImageXheader, distImageYheader; CvMat * distImageXreshaped = cvReshape(distImageX2, &distImageXheader, 0, 1); CvMat * distImageYreshaped = cvReshape(distImageY2, &distImageYheader, 0, 1); int w = srcImage->cols; int h = srcImage->rows; short * distx = (short*)distImageXreshaped->data.ptr; short * disty = (short*)distImageYreshaped->data.ptr; // Initialize index offsets for the current image width offset_u = -w; offset_ur = -w+1; offset_r = 1; offset_rd = w+1; offset_d = w; offset_dl = w-1; offset_l = -1; offset_lu = -w-1; /* Initialize the distance images to be all large values */ for(i=0; i<w*h; i++) // if(img(i) <= 0.0) if(CV_MAT_ELEM(*srcImage2, short, i/w, i%w) <= 0.0) { distx[i] = 32000; // Large but still representable in a short, and disty[i] = 32000; // 32000^2 + 32000^2 does not overflow an int } else {
void cvFillImage( CvArr* mat, double color ) { cvSet( mat, cvColorToScalar(color, cvGetElemType(mat)), 0 ); }
int CvArrTest::validate_test_results( int test_case_idx ) { static const char* arr_names[] = { "input", "input/output", "output", "ref input/output", "ref output", "temporary", "mask" }; int i, j; prepare_to_validation( test_case_idx ); for( i = 0; i < 2; i++ ) { int i0 = i == 0 ? OUTPUT : INPUT_OUTPUT; int i1 = i == 0 ? REF_OUTPUT : REF_INPUT_OUTPUT; int count = test_array[i0].size(); assert( count == test_array[i1].size() ); for( j = 0; j < count; j++ ) { double err_level; CvPoint idx = {0,0}; double max_diff = 0; int code; char msg[100]; if( !test_array[i1][j] ) continue; err_level = get_success_error_level( test_case_idx, i0, j ); code = cvTsCmpEps( &test_mat[i0][j], &test_mat[i1][j], &max_diff, err_level, &idx, element_wise_relative_error ); switch( code ) { case -1: sprintf( msg, "Too big difference (=%g)", max_diff ); code = CvTS::FAIL_BAD_ACCURACY; break; case -2: strcpy( msg, "Invalid output" ); code = CvTS::FAIL_INVALID_OUTPUT; break; case -3: strcpy( msg, "Invalid output in the reference array" ); code = CvTS::FAIL_INVALID_OUTPUT; break; default: continue; } ts->printf( CvTS::LOG, "%s in %s array %d at (%d,%d)\n", msg, arr_names[i0], j, idx.x, idx.y ); for( i0 = 0; i0 < max_arr; i0++ ) { int count = test_array[i0].size(); if( i0 == REF_INPUT_OUTPUT || i0 == OUTPUT || i0 == TEMP ) continue; for( i1 = 0; i1 < count; i1++ ) { CvArr* arr = test_array[i0][i1]; if( arr ) { CvSize size = cvGetSize(arr); int type = cvGetElemType(arr); ts->printf( CvTS::LOG, "%s array %d type=%sC%d, size=(%d,%d)\n", arr_names[i0], i1, cvTsGetTypeName(type), CV_MAT_CN(type), size.width, size.height ); } } } ts->set_failed_test_info( code ); return code; } } return 0; }
/** * Transforms points from the ground plane (z=-h) in the world frame * into points on the image in image frame (uv-coordinates) * * \param inPoints 2xN array of input points on the ground in world coordinates * \param outPoints 2xN output points in on the image in image coordinates * \param cameraInfo the camera parameters * */ void mcvTransformGround2Image(const CvMat *inPoints, CvMat *outPoints, const CameraInfo *cameraInfo) { //add two rows to the input points CvMat *inPoints3 = cvCreateMat(inPoints->rows+1, inPoints->cols, cvGetElemType(inPoints)); cvSet(inPoints3, cvScalar(0)); //copy inPoints to first two rows CvMat inPoints2, inPointsr3; cvGetRows(inPoints3, &inPoints2, 0, 2); cvGetRow(inPoints3, &inPointsr3, 2); cvSet(&inPointsr3, cvRealScalar(-cameraInfo->cameraHeight)); cvCopy(inPoints, &inPoints2); //create the transformation matrix float c1 = cos(cameraInfo->pitch); float s1 = sin(cameraInfo->pitch); float c2 = cos(cameraInfo->yaw); float s2 = sin(cameraInfo->yaw); float matp[] = { cameraInfo->focalLength.x * c2 + c1*s2* cameraInfo->opticalCenter.x, -cameraInfo->focalLength.x * s2 + c1*c2* cameraInfo->opticalCenter.x, - s1 * cameraInfo->opticalCenter.x, s2 * (-cameraInfo->focalLength.y * s1 + c1* cameraInfo->opticalCenter.y), c2 * (-cameraInfo->focalLength.y * s1 + c1* cameraInfo->opticalCenter.y), -cameraInfo->focalLength.y * c1 - s1* cameraInfo->opticalCenter.y, c1*s2, c1*c2, -s1 }; CvMat mat = cvMat(3, 3, FLOAT_MAT_TYPE, matp); //multiply //std::cout << " inPoints3.rows " << inPoints3->rows << " inPoints3.cols "<< inPoints3->cols << "\n "; cvMatMul(&mat, inPoints3, inPoints3); //divide by last row of inPoints4 for (int i=0; i<inPoints->cols; i++) { float div = CV_MAT_ELEM(inPointsr3, float, 0, i); CV_MAT_ELEM(*inPoints3, float, 0, i) = CV_MAT_ELEM(*inPoints3, float, 0, i) / div ; CV_MAT_ELEM(*inPoints3, float, 1, i) = CV_MAT_ELEM(*inPoints3, float, 1, i) / div; if(isnan(CV_MAT_ELEM(*inPoints3, float, 0, i) ) || isnan(CV_MAT_ELEM(*inPoints3, float, 1, i) )) { cout << "cameraInfo->pitch " << cameraInfo->pitch << endl; cout << "cameraInfo->yaw " << cameraInfo->yaw << endl; cout << "opticalCenter.x " << cameraInfo->opticalCenter.x << endl; cout << "opticalCenter.y " << cameraInfo->opticalCenter.y << endl; cout << "focalLength.x " << cameraInfo->focalLength.x << endl; cout << "focalLength.y " << cameraInfo->focalLength.y << endl; } //if(isnan(CV_MAT_ELEM(*inPoints3, float, 1, i) )) cout << "JAP!!!2 div " << div <<endl; } //put back the result into outPoints //std::cout << " inPoints2.rows " << inPoints2.rows << " inPoints2.cols "<< inPoints2.cols << "\n "; // std::cout << " outPoints.rows " << outPoints->rows << " outPoints.cols "<< outPoints->cols << "\n "; cvCopy(&inPoints2, outPoints); // std::cout << " outPoints.rows " << outPoints->rows << " outPoints.cols "<< outPoints->cols << "\n "; //clear cvReleaseMat(&inPoints3); }
/** * Transforms points from the image frame (uv-coordinates) * into the real world frame on the ground plane (z=-height) * * \param inPoints input points in the image frame * \param outPoints output points in the world frame on the ground * (z=-height) * \param cemaraInfo the input camera parameters * */ void mcvTransformImage2Ground(const CvMat *inPoints, CvMat *outPoints, const CameraInfo *cameraInfo) { //add two rows to the input points CvMat *inPoints4 = cvCreateMat(inPoints->rows+2, inPoints->cols, cvGetElemType(inPoints)); //copy inPoints to first two rows CvMat inPoints2, inPoints3, inPointsr4, inPointsr3; cvGetRows(inPoints4, &inPoints2, 0, 2); cvGetRows(inPoints4, &inPoints3, 0, 3); cvGetRow(inPoints4, &inPointsr3, 2); cvGetRow(inPoints4, &inPointsr4, 3); cvSet(&inPointsr3, cvRealScalar(1)); cvCopy(inPoints, &inPoints2); //create the transformation matrix float c1 = cos(cameraInfo->pitch); float s1 = sin(cameraInfo->pitch); float c2 = cos(cameraInfo->yaw); float s2 = sin(cameraInfo->yaw); float matp[] = { -cameraInfo->cameraHeight*c2/cameraInfo->focalLength.x, cameraInfo->cameraHeight*s1*s2/cameraInfo->focalLength.y, (cameraInfo->cameraHeight*c2*cameraInfo->opticalCenter.x/ cameraInfo->focalLength.x)- (cameraInfo->cameraHeight *s1*s2* cameraInfo->opticalCenter.y/ cameraInfo->focalLength.y) - cameraInfo->cameraHeight *c1*s2, cameraInfo->cameraHeight *s2 /cameraInfo->focalLength.x, cameraInfo->cameraHeight *s1*c2 /cameraInfo->focalLength.y, (-cameraInfo->cameraHeight *s2* cameraInfo->opticalCenter.x /cameraInfo->focalLength.x)-(cameraInfo->cameraHeight *s1*c2* cameraInfo->opticalCenter.y /cameraInfo->focalLength.y) - cameraInfo->cameraHeight *c1*c2, 0, cameraInfo->cameraHeight *c1 /cameraInfo->focalLength.y, (-cameraInfo->cameraHeight *c1* cameraInfo->opticalCenter.y / cameraInfo->focalLength.y) + cameraInfo->cameraHeight *s1, 0, -c1 /cameraInfo->focalLength.y, (c1* cameraInfo->opticalCenter.y /cameraInfo->focalLength.y) - s1, }; CvMat mat = cvMat(4, 3, CV_32FC1, matp); //multiply cvMatMul(&mat, &inPoints3, inPoints4); //divide by last row of inPoints4 for (int i=0; i<inPoints->cols; i++) { float div = CV_MAT_ELEM(inPointsr4, float, 0, i); CV_MAT_ELEM(*inPoints4, float, 0, i) = CV_MAT_ELEM(*inPoints4, float, 0, i) / div ; CV_MAT_ELEM(*inPoints4, float, 1, i) = CV_MAT_ELEM(*inPoints4, float, 1, i) / div; } //put back the result into outPoints cout << "cameraInfo->cameraHeight " << cameraInfo->cameraHeight << endl; cvCopy(&inPoints2, outPoints); //clear cvReleaseMat(&inPoints4); }
/*! \fn FaceDetectorPlugin::checkZone(Zone *zone, const Image *zmImage) * \param zone is a zone where faces will be detected * \param zmImage is an image to perform face detection (in the form of ZM' Image) * \return true if there were objects detected in given image and * false otherwise */ bool FaceDetectorPlugin::checkZone(Zone *zone, const Image *zmImage) { //log(LOG_DEBUG, "Entering checkZone."); double score; Polygon zone_polygon = Polygon(zone->GetPolygon()); // Polygon of interest of the processed zone. //char szMessage[50]; //sprintf(szMessage, "Polygon of the zone has %d vertices.", zone_polygon.getNumCoords()); //log(LOG_WARNING, szMessage); //zone->ResetStats(); /* log(LOG_WARNING, "precheck"); if ( !zone->CheckOverloadCount() ) { log(LOG_WARNING, "CheckOverloadCount() return false, we'll return false."); return(false); } */ //zmLoadConfig(); // An image for highlighting detected objects. Image *pMaskImage = new Image(zmImage->Width(), zmImage->Height(), ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ); pMaskImage->Fill(BLACK); //log(LOG_WARNING, "FILLBLACK."); // An temporary image in the form of ZM for making from it CvMat. // If don't use temp image, after rgb->bgr it will change. Image *tempZmImage = new Image(*zmImage); CvMat* cvInputImage = NULL; CvMat* pScaledImage = NULL; bool bDoResizing = (m_fImageScaleFactor != 1.0); // resize image or not if (tempZmImage->Colours() == ZM_COLOUR_GRAY8) { // if image is not colored, create an one-channel CvMat. cvInputImage = cvCreateMat(tempZmImage->Height(), tempZmImage->Width(), CV_8UC1); unsigned char *buffer = (unsigned char*)tempZmImage->Buffer(); cvSetData(cvInputImage, buffer, tempZmImage->Width()); } // NEXTIME XXX TODO: manage also 32 bit images! else { // otherwise create a three-channel CvMat and then convert colors from RGB to BGR. cvInputImage = cvCreateMat(tempZmImage->Height(), tempZmImage->Width(), CV_8UC3); unsigned char *buffer = (unsigned char*)tempZmImage->Buffer(); cvSetData(cvInputImage, buffer, tempZmImage->Width() * 3); cvCvtColor(cvInputImage, cvInputImage, CV_RGB2BGR); } if (bDoResizing) { int nNewWidth = int (m_fImageScaleFactor * zmImage->Width()); int nNewHeight = int (m_fImageScaleFactor * tempZmImage->Height()); int nImageElemType = cvGetElemType(cvInputImage); pScaledImage = cvCreateMat(nNewHeight, nNewWidth, nImageElemType); cvResize(cvInputImage, pScaledImage, CV_INTER_LINEAR); } //Process image vector<CvRect> foundObjects; if (bDoResizing) foundObjects = _opencvHaarDetect(pScaledImage); else foundObjects = _opencvHaarDetect(cvInputImage); if (foundObjects.size() > 0) log(LOG_INFO, "OBJECTS WERE DETECTED"); score = 0; for (vector<CvRect>::iterator it = foundObjects.begin(); it < foundObjects.end(); it++) { // Process found objects. // Scale object's coordinates back if image has been scaled. int x1 = int(it->x/m_fImageScaleFactor), x2 = int((it->x + it->width)/m_fImageScaleFactor), y1 = int(it->y/m_fImageScaleFactor), y2 = int((it->y + it->height)/m_fImageScaleFactor); // Check if object's rectangle is inside zone's polygon of interest. Coord rectVertCoords[4] = {Coord(x1, y1), Coord(x1, y2), Coord(x2, y1), Coord(x2, y2)}; int nNumVertInside = 0; for (int i = 0; i < 4; i++) { nNumVertInside += zone_polygon.isInside(rectVertCoords[i]); } if (nNumVertInside < 3) // if at least three rectangle coordinates are inside polygon, consider rectangle as belonging to the zone // otherwise process next object continue; // Fill a box with object in the mask Box *faceBox = new Box(x1, y1, x2, y2); pMaskImage->Fill(WHITE, faceBox); // Calculate score as portion of object area in the image score += (100.0*(it->width)*(it->height)/m_fImageScaleFactor/m_fImageScaleFactor)/zone_polygon.Area(); delete faceBox; } if (score == 0) { //log(LOG_DEBUG, "No objects found. Exit."); delete pMaskImage; delete tempZmImage; if (cvInputImage) cvReleaseMat(&cvInputImage); if (pScaledImage) cvReleaseMat(&pScaledImage); return( false ); } if ( m_fMinAlarmScore && ( score < m_fMinAlarmScore) ) { delete pMaskImage; delete tempZmImage; if (cvInputImage) cvReleaseMat(&cvInputImage); if (pScaledImage) cvReleaseMat(&pScaledImage); return( false ); } if ( m_fMaxAlarmScore && (score > m_fMaxAlarmScore) ) { zone->SetOverloadCount(zone->GetOverloadFrames()); delete pMaskImage; delete tempZmImage; if (cvInputImage) cvReleaseMat(&cvInputImage); if (pScaledImage) cvReleaseMat(&pScaledImage); return( false ); } zone->SetScore(max(1, (int)score)); //Get mask by highlighting contours of objects and overlaying them with previous contours. Rgb alarm_colour = RGB_GREEN; Image *hlZmImage = pMaskImage->HighlightEdges(alarm_colour, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB, &zone_polygon.Extent()); if (zone->Alarmed()) { // if there were previous detection and they have already set up alarm image // then overlay it with current mask Image* pPrevZoneMask = new Image(*(zone->AlarmImage())); pPrevZoneMask->Overlay(*hlZmImage); zone->SetAlarmImage(pPrevZoneMask); delete pPrevZoneMask; } else zone->SetAlarmImage(hlZmImage); delete pMaskImage; delete hlZmImage; delete tempZmImage; if (cvInputImage) cvReleaseMat(&cvInputImage); if (pScaledImage) cvReleaseMat(&pScaledImage); //log(LOG_DEBUG, "Leaving checkZone."); return true; }
/* Warps source into destination by a perspective transform */ static void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] ) { CV_FUNCNAME( "cvWarpPerspective" ); __BEGIN__; #ifdef __IPL_H__ IplImage src_stub, dst_stub; IplImage* src_img; IplImage* dst_img; CV_CALL( src_img = cvGetImage( src, &src_stub ) ); CV_CALL( dst_img = cvGetImage( dst, &dst_stub ) ); iplWarpPerspectiveQ( src_img, dst_img, quad, IPL_WARP_R_TO_Q, IPL_INTER_CUBIC | IPL_SMOOTH_EDGE ); #else int fill_value = 0; double c[3][3]; /* transformation coefficients */ double q[4][2]; /* rearranged quad */ int left = 0; int right = 0; int next_right = 0; int next_left = 0; double y_min = 0; double y_max = 0; double k_left, b_left, k_right, b_right; uchar* src_data; int src_step; CvSize src_size; uchar* dst_data; int dst_step; CvSize dst_size; double d = 0; int direction = 0; int i; if( !src || (!CV_IS_IMAGE( src ) && !CV_IS_MAT( src )) || cvGetElemType( src ) != CV_8UC1 || cvGetDims( src ) != 2 ) { CV_ERROR( CV_StsBadArg, "Source must be two-dimensional array of CV_8UC1 type." ); } if( !dst || (!CV_IS_IMAGE( dst ) && !CV_IS_MAT( dst )) || cvGetElemType( dst ) != CV_8UC1 || cvGetDims( dst ) != 2 ) { CV_ERROR( CV_StsBadArg, "Destination must be two-dimensional array of CV_8UC1 type." ); } CV_CALL( cvGetRawData( src, &src_data, &src_step, &src_size ) ); CV_CALL( cvGetRawData( dst, &dst_data, &dst_step, &dst_size ) ); CV_CALL( cvGetPerspectiveTransform( src_size, quad, c ) ); /* if direction > 0 then vertices in quad follow in a CW direction, otherwise they follow in a CCW direction */ direction = 0; for( i = 0; i < 4; ++i ) { int ni = i + 1; if( ni == 4 ) ni = 0; int pi = i - 1; if( pi == -1 ) pi = 3; d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) - (quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]); int cur_direction = CV_SIGN(d); if( direction == 0 ) { direction = cur_direction; } else if( direction * cur_direction < 0 ) { direction = 0; break; } } if( direction == 0 ) { CV_ERROR( CV_StsBadArg, "Quadrangle is nonconvex or degenerated." ); } /* <left> is the index of the topmost quad vertice if there are two such vertices <left> is the leftmost one */ left = 0; for( i = 1; i < 4; ++i ) { if( (quad[i][1] < quad[left][1]) || ((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) ) { left = i; } } /* rearrange <quad> vertices in such way that they follow in a CW direction and the first vertice is the topmost one and put them into <q> */ if( direction > 0 ) { for( i = left; i < 4; ++i ) { q[i-left][0] = quad[i][0]; q[i-left][1] = quad[i][1]; } for( i = 0; i < left; ++i ) { q[4-left+i][0] = quad[i][0]; q[4-left+i][1] = quad[i][1]; } } else { for( i = left; i >= 0; --i ) { q[left-i][0] = quad[i][0]; q[left-i][1] = quad[i][1]; } for( i = 3; i > left; --i ) { q[4+left-i][0] = quad[i][0]; q[4+left-i][1] = quad[i][1]; } } left = right = 0; /* if there are two topmost points, <right> is the index of the rightmost one otherwise <right> */ if( q[left][1] == q[left+1][1] ) { right = 1; } /* <next_left> follows <left> in a CCW direction */ next_left = 3; /* <next_right> follows <right> in a CW direction */ next_right = right + 1; /* subtraction of 1 prevents skipping of the first row */ y_min = q[left][1] - 1; /* left edge equation: y = k_left * x + b_left */ k_left = (q[left][0] - q[next_left][0]) / (q[left][1] - q[next_left][1]); b_left = (q[left][1] * q[next_left][0] - q[left][0] * q[next_left][1]) / (q[left][1] - q[next_left][1]); /* right edge equation: y = k_right * x + b_right */ k_right = (q[right][0] - q[next_right][0]) / (q[right][1] - q[next_right][1]); b_right = (q[right][1] * q[next_right][0] - q[right][0] * q[next_right][1]) / (q[right][1] - q[next_right][1]); for(;;) { int x, y; y_max = MIN( q[next_left][1], q[next_right][1] ); int iy_min = MAX( cvRound(y_min), 0 ) + 1; int iy_max = MIN( cvRound(y_max), dst_size.height - 1 ); double x_min = k_left * iy_min + b_left; double x_max = k_right * iy_min + b_right; /* walk through the destination quadrangle row by row */ for( y = iy_min; y <= iy_max; ++y ) { int ix_min = MAX( cvRound( x_min ), 0 ); int ix_max = MIN( cvRound( x_max ), dst_size.width - 1 ); for( x = ix_min; x <= ix_max; ++x ) { /* calculate coordinates of the corresponding source array point */ double div = (c[2][0] * x + c[2][1] * y + c[2][2]); double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div; double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div; int isrc_x = cvFloor( src_x ); int isrc_y = cvFloor( src_y ); double delta_x = src_x - isrc_x; double delta_y = src_y - isrc_y; uchar* s = src_data + isrc_y * src_step + isrc_x; int i00, i10, i01, i11; i00 = i10 = i01 = i11 = (int) fill_value; /* linear interpolation using 2x2 neighborhood */ if( isrc_x >= 0 && isrc_x <= src_size.width && isrc_y >= 0 && isrc_y <= src_size.height ) { i00 = s[0]; } if( isrc_x >= -1 && isrc_x < src_size.width && isrc_y >= 0 && isrc_y <= src_size.height ) { i10 = s[1]; } if( isrc_x >= 0 && isrc_x <= src_size.width && isrc_y >= -1 && isrc_y < src_size.height ) { i01 = s[src_step]; } if( isrc_x >= -1 && isrc_x < src_size.width && isrc_y >= -1 && isrc_y < src_size.height ) { i11 = s[src_step+1]; } double i0 = i00 + (i10 - i00)*delta_x; double i1 = i01 + (i11 - i01)*delta_x; ((uchar*)(dst_data + y * dst_step))[x] = (uchar) (i0 + (i1 - i0)*delta_y); } x_min += k_left; x_max += k_right; } if( (next_left == next_right) || (next_left+1 == next_right && q[next_left][1] == q[next_right][1]) ) { break; } if( y_max == q[next_left][1] ) { left = next_left; next_left = left - 1; k_left = (q[left][0] - q[next_left][0]) / (q[left][1] - q[next_left][1]); b_left = (q[left][1] * q[next_left][0] - q[left][0] * q[next_left][1]) / (q[left][1] - q[next_left][1]); } if( y_max == q[next_right][1] ) { right = next_right; next_right = right + 1; k_right = (q[right][0] - q[next_right][0]) / (q[right][1] - q[next_right][1]); b_right = (q[right][1] * q[next_right][0] - q[right][0] * q[next_right][1]) / (q[right][1] - q[next_right][1]); } y_min = y_max; } #endif /* #ifndef __IPL_H__ */ __END__; }
bool MT_Cholesky(const CvMat* src, CvMat* dst, unsigned int orientation) { if(!check_size_type(src, "Input")) { return false; } if(!dst) { fprintf(stderr, "MT_Cholesky Error: Output is not allocated.\n"); return false; } else { if((dst->rows != src->rows) || (dst->cols != src->cols) || (cvGetElemType(dst) != cvGetElemType(src))) { fprintf(stderr, "MT_Cholesky Error: Output matrix must be same size" " and type as input.\n"); return false; } } if((orientation != MT_CHOLESKY_UPPER_TRIANGULAR) && (orientation != MT_CHOLESKY_LOWER_TRIANGULAR)) { fprintf(stderr, "MT_Cholesky Error: Orientation must be either " "MT_CHOLESKY_UPPER_TRIANGULAR (%d) or " "MT_CHOLESKY_LOWER_TRIANGULAR (%d).\n", MT_CHOLESKY_UPPER_TRIANGULAR, MT_CHOLESKY_LOWER_TRIANGULAR); return false; } double p; unsigned int R = src->rows; cvSet(dst, cvScalar(0)); double* src_data = src->data.db; double* dst_data = dst->data.db; for(int i = 0; i < R; i++) { for(int j = 0; j < R; j++) { if(i < j) { continue; } p = 0; if(i==j) { p = src_data[i*R + i]; for(int k = 0; k <= j-1; k++) { p -= dst_data[i*R+k]*dst_data[i*R+k]; } if( p < 0 ){ // NOTE these may not be numerically correct, but it is a safeguard p = fabs(p); } if( p == 0 ){ p = 1e-6; } dst_data[i*R+i] = sqrt(p); } else { p = src_data[i*R+j]; for(int k = 0; k <= j-1; k++) { p -= dst_data[i*R+k]*dst_data[j*R+k]; } dst_data[i*R+j] = p/dst_data[j*R+j]; } } } if(orientation == MT_CHOLESKY_UPPER_TRIANGULAR) { cvTranspose(dst, dst); } return true; }