/* Changes RNG range while preserving RNG state */ void cvRandSetRange( CvRandState* state, double param1, double param2, int index) { if( !state ) { cvError( CV_StsNullPtr, "cvRandSetRange", "Null pointer to RNG state", "cvcompat.h", 0 ); return; } if( (unsigned)(index + 1) > 4 ) { cvError( CV_StsOutOfRange, "cvRandSetRange", "index is not in -1..3", "cvcompat.h", 0 ); return; } if( index < 0 ) { state->param[0].val[0] = state->param[0].val[1] = state->param[0].val[2] = state->param[0].val[3] = param1; state->param[1].val[0] = state->param[1].val[1] = state->param[1].val[2] = state->param[1].val[3] = param2; } else { state->param[0].val[index] = param1; state->param[1].val[index] = param2; } }
// 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); } }
Mat Histogram::applyKernel(int size,int type) { if(_histMat.channels()>1) cvError(1,__FUNCTION__,"Only for 1D histograms",__FILE__,__LINE__); Mat output; Mat input=cv::Mat(1,3,CV_32FC1); Mat kernel=cv::Mat(size,1,CV_32FC1); if(type==1) { kernel.setTo(cv::Scalar::all(1)); input.setTo(cv::Scalar::all(1)); } else if(type==2) { kernel=getGaussianKernel(256,size,CV_32FC1); } Scalar sum=cv::sum(kernel); cv::filter2D(_histMat,output,_histMat.depth(),kernel,Point(-1,-1),0,BORDER_CONSTANT); if(type==1) { output.convertTo(output,output.type(),1.0/sum[0],0); } return output; }
Mat Histogram::drawHist(MatND _histMat) { if(_histMat.channels()>1) cvError(1,__FUNCTION__,"Only for 1D histograms",__FILE__,__LINE__); int w = 400; int h = 400; Mat histImage( h, w, CV_8UC3, Scalar( 0,0,0) ); Mat i2; cv::normalize(_histMat,i2,0,255,CV_MINMAX); for( int i = 0; i < _histSize[0]; i++ ) { int bin_w = cvRound( (double) w/_histSize[0]); rectangle( histImage, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( i2.at<float>(i)*h/255.0 ) ), Scalar( 0, 0, 255 ), -1 ); /*line( histImage, Point( bin_w*(i-1), hist_h - cvRound(1*i2.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(1*i2.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 ); /*line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ), Scalar( 0, 255, 0), 2, 8, 0 ); line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) , Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ), Scalar( 0, 0, 255), 2, 8, 0 );*/ } return histImage; }
/* Fills array with random numbers */ void cvRand( CvRandState* state, CvArr* arr ) { if( !state ) { cvError( CV_StsNullPtr, "cvRand", "Null pointer to RNG state", "cvcompat.h", 0 ); return; } cvRandArr( &state->state, arr, state->disttype, state->param[0], state->param[1] ); }
void cvRandInit( CvRandState* state, double param1, double param2, int seed, int disttype) { if( !state ) { cvError( CV_StsNullPtr, "cvRandInit", "Null pointer to RNG state", "cvcompat.h", 0 ); return; } if( disttype != CV_RAND_UNI && disttype != CV_RAND_NORMAL ) { cvError( CV_StsBadFlag, "cvRandInit", "Unknown distribution type", "cvcompat.h", 0 ); return; } state->state = (uint64)(seed ? seed : -1); state->disttype = disttype; cvRandSetRange( state, param1, param2, -1 ); }
void cvStartScanGraph( CvGraph* graph, CvGraphScanner* scanner, CvGraphVtx* vtx, int mask) { CvGraphScanner* temp_scanner; if( !scanner ) cvError( CV_StsNullPtr, "cvStartScanGraph", "Null scanner pointer", "cvcompat.h", 0 ); temp_scanner = cvCreateGraphScanner( graph, vtx, mask ); *scanner = *temp_scanner; cvFree( &temp_scanner ); }
void cvEndScanGraph( CvGraphScanner* scanner ) { if( !scanner ) cvError( CV_StsNullPtr, "cvEndScanGraph", "Null scanner pointer", "cvcompat.h", 0 ); if( scanner->stack ) { CvGraphScanner* temp_scanner = (CvGraphScanner*)cvAlloc( sizeof(*temp_scanner) ); *temp_scanner = *scanner; cvReleaseGraphScanner( &temp_scanner ); memset( scanner, 0, sizeof(*scanner) ); } }
/** * Note: if lowDensity < blankDensityThreshold -> blank; * else if highDensity > messyDensityThreshold -> messy; * else -> good; */ Smoothness compute_smoothness(const IplImage *pFourierImage, const double lowFreqRatio, const double blankDensity, const double messyDensity, const double highFreqRatio, double &outLowDensity, double &outHighDensity) { int low, high; IplImage *filteredFourierImage; int totalIntensity; double sum, den, totalArea; CvScalar scalar; if(! (pFourierImage->nChannels == 1 && pFourierImage->depth == 64) ) { cvError( CV_StsUnmatchedSizes, "compute_smoothness", "input image must contain only 1 channel and a depth of 64", __FILE__, __LINE__ ); } high_pass_range(pFourierImage, lowFreqRatio, low, high ); totalArea = M_PI * (high * high - low * low); filteredFourierImage = create_frequency_filtered_image(pFourierImage, low, high); scalar = cvSum(filteredFourierImage); totalIntensity = scalar.val[0]; cvReleaseImage(&filteredFourierImage); outLowDensity = den = totalIntensity / totalArea; if(den <= blankDensity) { return BLANK; } low = (int) (high * (1.0 - highFreqRatio)); filteredFourierImage = create_frequency_filtered_image(pFourierImage, low, high); scalar = cvSum(filteredFourierImage); totalIntensity = scalar.val[0]; cvReleaseImage(&filteredFourierImage); outHighDensity = den = totalIntensity / totalArea; if(den >= messyDensity) { return MESSY; } return SMOOTH; }
// does a fast check if a chessboard is in the input image. This is a workaround to // a problem of cvFindChessboardCorners being slow on images with no chessboard // - src: input image // - size: chessboard size // Returns 1 if a chessboard can be in this image and findChessboardCorners should be called, // 0 if there is no chessboard, -1 in case of error int cvCheckChessboard(IplImage* src, CvSize size) { if(src->nChannels > 1) { cvError(CV_BadNumChannels, "cvCheckChessboard", "supports single-channel images only", __FILE__, __LINE__); } if(src->depth != 8) { cvError(CV_BadDepth, "cvCheckChessboard", "supports depth=8 images only", __FILE__, __LINE__); } const int erosion_count = 1; const float black_level = 20.f; const float white_level = 130.f; const float black_white_gap = 70.f; #if defined(DEBUG_WINDOWS) cvNamedWindow("1", 1); cvShowImage("1", src); cvWaitKey(0); #endif //DEBUG_WINDOWS CvMemStorage* storage = cvCreateMemStorage(); IplImage* white = cvCloneImage(src); IplImage* black = cvCloneImage(src); cvErode(white, white, NULL, erosion_count); cvDilate(black, black, NULL, erosion_count); IplImage* thresh = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); int result = 0; for(float thresh_level = black_level; thresh_level < white_level && !result; thresh_level += 20.0f) { cvThreshold(white, thresh, thresh_level + black_white_gap, 255, CV_THRESH_BINARY); #if defined(DEBUG_WINDOWS) cvShowImage("1", thresh); cvWaitKey(0); #endif //DEBUG_WINDOWS CvSeq* first = 0; std::vector<std::pair<float, int> > quads; cvFindContours(thresh, storage, &first, sizeof(CvContour), CV_RETR_CCOMP); icvGetQuadrangleHypotheses(first, quads, 1); cvThreshold(black, thresh, thresh_level, 255, CV_THRESH_BINARY_INV); #if defined(DEBUG_WINDOWS) cvShowImage("1", thresh); cvWaitKey(0); #endif //DEBUG_WINDOWS cvFindContours(thresh, storage, &first, sizeof(CvContour), CV_RETR_CCOMP); icvGetQuadrangleHypotheses(first, quads, 0); const size_t min_quads_count = size.width*size.height/2; std::sort(quads.begin(), quads.end(), less_pred); // now check if there are many hypotheses with similar sizes // do this by floodfill-style algorithm const float size_rel_dev = 0.4f; for(size_t i = 0; i < quads.size(); i++) { size_t j = i + 1; for(; j < quads.size(); j++) { if(quads[j].first/quads[i].first > 1.0f + size_rel_dev) { break; } } if(j + 1 > min_quads_count + i) { // check the number of black and white squares std::vector<int> counts; countClasses(quads, i, j, counts); const int black_count = cvRound(ceil(size.width/2.0)*ceil(size.height/2.0)); const int white_count = cvRound(floor(size.width/2.0)*floor(size.height/2.0)); if(counts[0] < black_count*0.75 || counts[1] < white_count*0.75) { continue; } result = 1; break; } } } cvReleaseImage(&thresh); cvReleaseImage(&white); cvReleaseImage(&black); cvReleaseMemStorage(&storage); return result; }