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;
}
void Analyser::compareToHistogram(Mat &image, Mat &histo, Mat &result) {
	
    Mat img_blur(image.rows, image.cols, image.type());
    GaussianBlur(image, img_blur, Size(0,0), 3);
    
	Mat img_hsv(img_blur.rows, img_blur.cols, image.type());
	cvtColor(img_blur, img_hsv, CV_BGR2HSV);
	
    /// Use only the Hue value
    Mat hue, saturation, brightness;
    hue.create( img_hsv.size(), img_hsv.depth() );
    saturation.create( img_hsv.size(), img_hsv.depth() );
    brightness.create( img_hsv.size(), img_hsv.depth() );
    
    int chH[] = { 0, 0 };
    mixChannels( &img_hsv, 1, &hue, 1, chH, 1 );
    int chS[] = { 1, 0 };
    mixChannels( &img_hsv, 1, &saturation, 1, chS, 1 );
    int chB[] = { 2, 0 };
    mixChannels( &img_hsv, 1, &brightness, 1, chB, 1 );
    
    Mat planes[] = {hue, saturation};
	
	result = Mat(image.rows, image.cols, CV_8UC1, Scalar(0));
	
	float h_ranges[] = {0,180};
	float s_ranges[] = {0,255};
    const float* ranges[] = {h_ranges, s_ranges};
    
    MatND backproj;
    calcBackProject( planes, 2, 0, histo, backproj, ranges, 1, true );
    normalize( backproj, backproj, 0, 255, NORM_MINMAX, -1, Mat() );
    
    // On enlève les valeurs trop sombres
    for (int y=0 ; y<brightness.rows; y++) {
        for (int x=0 ; x<brightness.cols; x++) {
            if (brightness.data[brightness.step*y+x] < 50) {
                backproj.data[backproj.step * y + x ] = 0;
            }
        }
    }
    
    backproj.copyTo(result);
    
}
Mat RadialHistogramClassifier::caracteristicVector(const Mat &segmentedHand) {
    Mat direction = handDirection(segmentedHand).second;
    float angle = atan(direction.at<float>(0,1)/direction.at<float>(0,0));
    Mat rotatedHand;
    rotateHand(segmentedHand, rotatedHand, angle);
    Mat flippedHand = rotatedHand;
    if (detectHandSide(rotatedHand, 1) == LEFT_HAND) {
        horizontalSymmetry(rotatedHand, flippedHand);
    }
    MatND handRadialHistogram;
    Point2f palmCenter = estimatePalmCenter(
           flippedHand, 
           this->maxFingerWidth);
    radialHistogramWithCenter(
        flippedHand, 
        handRadialHistogram, 
        this->numberOfBins, 
        palmCenter);
    return handRadialHistogram.t();
}
Exemple #4
0
void CV_ArrayOpTest::run( int /* start_from */)
{
    int errcount = 0;

    // dense matrix operations
    {
        int sz3[] = {5, 10, 15};
        MatND A(3, sz3, CV_32F), B(3, sz3, CV_16SC4);
        CvMatND matA = A, matB = B;
        RNG rng;
        rng.fill(A, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));
        rng.fill(B, CV_RAND_UNI, Scalar::all(-10), Scalar::all(10));

        int idx0[] = {3,4,5}, idx1[] = {0, 9, 7};
        float val0 = 130;
        Scalar val1(-1000, 30, 3, 8);
        cvSetRealND(&matA, idx0, val0);
        cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0);
        cvSetND(&matB, idx0, val1);
        cvSet3D(&matB, idx1[0], idx1[1], idx1[2], -val1);
        Ptr<CvMatND> matC = cvCloneMatND(&matB);

        if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
                A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
                cvGetReal3D(&matA, idx0[0], idx0[1], idx0[2]) != val0 ||
                cvGetRealND(&matA, idx1) != -val0 ||

                Scalar(B.at<Vec4s>(idx0[0], idx0[1], idx0[2])) != val1 ||
                Scalar(B.at<Vec4s>(idx1[0], idx1[1], idx1[2])) != -val1 ||
                Scalar(cvGet3D(matC, idx0[0], idx0[1], idx0[2])) != val1 ||
                Scalar(cvGetND(matC, idx1)) != -val1 )
        {
            ts->printf(CvTS::LOG, "one of cvSetReal3D, cvSetRealND, cvSet3D, cvSetND "
                       "or the corresponding *Get* functions is not correct\n");
            errcount++;
        }
    }

    RNG rng;
    const int MAX_DIM = 5, MAX_DIM_SZ = 10;
    // sparse matrix operations
    for( int si = 0; si < 10; si++ )
    {
        int depth = (unsigned)rng % 2 == 0 ? CV_32F : CV_64F;
        int dims = ((unsigned)rng % MAX_DIM) + 1;
        int i, k, size[MAX_DIM]= {0}, idx[MAX_DIM]= {0};
        vector<string> all_idxs;
        vector<double> all_vals;
        vector<double> all_vals2;
        string sidx, min_sidx, max_sidx;
        double min_val=0, max_val=0;

        int p = 1;
        for( k = 0; k < dims; k++ )
        {
            size[k] = ((unsigned)rng % MAX_DIM_SZ) + 1;
            p *= size[k];
        }
        SparseMat M( dims, size, depth );
        map<string, double> M0;

        int nz0 = (unsigned)rng % max(p/5,10);
        nz0 = min(max(nz0, 1), p);
        all_vals.resize(nz0);
        all_vals2.resize(nz0);
        Mat_<double> _all_vals(all_vals), _all_vals2(all_vals2);
        rng.fill(_all_vals, CV_RAND_UNI, Scalar(-1000), Scalar(1000));
        if( depth == CV_32F )
        {
            Mat _all_vals_f;
            _all_vals.convertTo(_all_vals_f, CV_32F);
            _all_vals_f.convertTo(_all_vals, CV_64F);
        }
        _all_vals.convertTo(_all_vals2, _all_vals2.type(), 2);
        if( depth == CV_32F )
        {
            Mat _all_vals2_f;
            _all_vals2.convertTo(_all_vals2_f, CV_32F);
            _all_vals2_f.convertTo(_all_vals2, CV_64F);
        }

        minMaxLoc(_all_vals, &min_val, &max_val);
        double _norm0 = norm(_all_vals, CV_C);
        double _norm1 = norm(_all_vals, CV_L1);
        double _norm2 = norm(_all_vals, CV_L2);

        for( i = 0; i < nz0; i++ )
        {
            for(;;)
            {
                for( k = 0; k < dims; k++ )
                    idx[k] = (unsigned)rng % size[k];
                sidx = idx2string(idx, dims);
                if( M0.count(sidx) == 0 )
                    break;
            }
            all_idxs.push_back(sidx);
            M0[sidx] = all_vals[i];
            if( all_vals[i] == min_val )
                min_sidx = sidx;
            if( all_vals[i] == max_val )
                max_sidx = sidx;
            setValue(M, idx, all_vals[i], rng);
            double v = getValue(M, idx, rng);
            if( v != all_vals[i] )
            {
                ts->printf(CvTS::LOG, "%d. immediately after SparseMat[%s]=%.20g the current value is %.20g\n",
                           i, sidx.c_str(), all_vals[i], v);
                errcount++;
                break;
            }
        }

        Ptr<CvSparseMat> M2 = (CvSparseMat*)M;
        MatND Md;
        M.copyTo(Md);
        SparseMat M3;
        SparseMat(Md).convertTo(M3, Md.type(), 2);

        int nz1 = (int)M.nzcount(), nz2 = (int)M3.nzcount();
        double norm0 = norm(M, CV_C);
        double norm1 = norm(M, CV_L1);
        double norm2 = norm(M, CV_L2);
        double eps = depth == CV_32F ? FLT_EPSILON*100 : DBL_EPSILON*1000;

        if( nz1 != nz0 || nz2 != nz0)
        {
            errcount++;
            ts->printf(CvTS::LOG, "%d: The number of non-zero elements before/after converting to/from dense matrix is not correct: %d/%d (while it should be %d)\n",
                       si, nz1, nz2, nz0 );
            break;
        }

        if( fabs(norm0 - _norm0) > fabs(_norm0)*eps ||
                fabs(norm1 - _norm1) > fabs(_norm1)*eps ||
                fabs(norm2 - _norm2) > fabs(_norm2)*eps )
        {
            errcount++;
            ts->printf(CvTS::LOG, "%d: The norms are different: %.20g/%.20g/%.20g vs %.20g/%.20g/%.20g\n",
                       si, norm0, norm1, norm2, _norm0, _norm1, _norm2 );
            break;
        }

        int n = (unsigned)rng % max(p/5,10);
        n = min(max(n, 1), p) + nz0;

        for( i = 0; i < n; i++ )
        {
            double val1, val2, val3, val0;
            if(i < nz0)
            {
                sidx = all_idxs[i];
                string2idx(sidx, idx, dims);
                val0 = all_vals[i];
            }
            else
            {
                for( k = 0; k < dims; k++ )
                    idx[k] = (unsigned)rng % size[k];
                sidx = idx2string(idx, dims);
                val0 = M0[sidx];
            }
            val1 = getValue(M, idx, rng);
            val2 = getValue(M2, idx);
            val3 = getValue(M3, idx, rng);

            if( val1 != val0 || val2 != val0 || fabs(val3 - val0*2) > fabs(val0*2)*FLT_EPSILON )
            {
                errcount++;
                ts->printf(CvTS::LOG, "SparseMat M[%s] = %g/%g/%g (while it should be %g)\n", sidx.c_str(), val1, val2, val3, val0 );
                break;
            }
        }

        for( i = 0; i < n; i++ )
        {
            double val1, val2;
            if(i < nz0)
            {
                sidx = all_idxs[i];
                string2idx(sidx, idx, dims);
            }
            else
            {
                for( k = 0; k < dims; k++ )
                    idx[k] = (unsigned)rng % size[k];
                sidx = idx2string(idx, dims);
            }
            eraseValue(M, idx, rng);
            eraseValue(M2, idx);
            val1 = getValue(M, idx, rng);
            val2 = getValue(M2, idx);
            if( val1 != 0 || val2 != 0 )
            {
                errcount++;
                ts->printf(CvTS::LOG, "SparseMat: after deleting M[%s], it is =%g/%g (while it should be 0)\n", sidx.c_str(), val1, val2 );
                break;
            }
        }

        int nz = (int)M.nzcount();
        if( nz != 0 )
        {
            errcount++;
            ts->printf(CvTS::LOG, "The number of non-zero elements after removing all the elements = %d (while it should be 0)\n", nz );
            break;
        }

        int idx1[MAX_DIM], idx2[MAX_DIM];
        double val1 = 0, val2 = 0;
        M3 = SparseMat(Md);
        minMaxLoc(M3, &val1, &val2, idx1, idx2);
        string s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
        if( val1 != min_val || val2 != max_val || s1 != min_sidx || s2 != max_sidx )
        {
            errcount++;
            ts->printf(CvTS::LOG, "%d. Sparse: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t"
                       "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
                       min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
            break;
        }

        minMaxLoc(Md, &val1, &val2, idx1, idx2);
        s1 = idx2string(idx1, dims), s2 = idx2string(idx2, dims);
        if( (min_val < 0 && (val1 != min_val || s1 != min_sidx)) ||
                (max_val > 0 && (val2 != max_val || s2 != max_sidx)) )
        {
            errcount++;
            ts->printf(CvTS::LOG, "%d. Dense: The value and positions of minimum/maximum elements are different from the reference values and positions:\n\t"
                       "(%g, %g, %s, %s) vs (%g, %g, %s, %s)\n", si, val1, val2, s1.c_str(), s2.c_str(),
                       min_val, max_val, min_sidx.c_str(), max_sidx.c_str());
            break;
        }
    }

    ts->set_failed_test_info(errcount == 0 ? CvTS::OK : CvTS::FAIL_INVALID_OUTPUT);
}
void CHumanTracker::generateRegionHistogram(Mat& region, MatND &hist, bool vis)
{
	MatND prior = hist.clone();

	Mat hsv;
	cvtColor(region, hsv, CV_BGR2HSV);

	Mat mask = Mat::zeros(region.rows, region.cols, CV_8UC1);
	for (int r = 0; r < region.rows; r++)
	{
		for (int c = 0; c < region.cols; c++)
		{
			unsigned int v = hsv.at<Vec3b>(r,c)[2];
			// TODO: Make me parameters
            if (( v > 10) && (v < 240))
			{
				mask.at<uchar>(r,c) = 1;
			}
		}
	}

//	namedWindow( "Face Mask", 1 );
//	imshow( "Face Mask", mask * 255 );

	int histSize[] = {hbins, sbins};
	float hranges[] = {0, 180};
	float sranges[] = {0, 256};
	const float* ranges[] = { hranges, sranges};
	int channels[] = {0, 1};
	calcHist(&hsv, 1, channels, mask, hist, 2, histSize, ranges, true, false);

	for( int h = 0; h < hbins; h++ )
	{
		for( int s = 0; s < sbins; s++ )
		{
			hist.at<float>(h,s) = (0.99 * prior.at<float>(h,s)) + (0.01 * hist.at<float>(h,s));
		}
	}

	// We should make it a probability dist.
	normalize(hist, hist, 1.0, 0.0, NORM_L1);

	if (vis)
	{
		// For vis
		Mat visHist;
		normalize(hist, visHist, 255.0, 0.00, NORM_MINMAX);

		int scale = 10;
		Mat histImg = Mat::zeros(sbins * scale, hbins* scale, CV_8UC3);
		for( int h = 0; h < hbins; h++ )
		{
			for( int s = 0; s < sbins; s++ )
			{
				float binVal = visHist.at<float>(h, s);
				int intensity = cvRound(binVal);///maxVal);
				rectangle( histImg, Point(h*scale, s*scale),
							Point( (h+1)*scale - 1, (s+1)*scale - 1),
							Scalar::all(intensity),
							CV_FILLED );
			}
		}

        if ((debugLevel & 0x08) == 0x08)
        {
            namedWindow( "H-S Histogram", 1 );
            imshow( "H-S Histogram", histImg );
            waitKey(1);
        }
	}
}
Exemple #6
0
/*
 *	功能:直方图相似度计算和匹配
 *  参数:
 *  状态:
 */
int histMatch()
{
    Mat frame,img;
    Mat staRoiHist;
    MatND RoiHist;
    int DRAW_H=400,DRAW_W=400;
    Mat draw(DRAW_W,DRAW_H,CV_8UC3,Scalar(0,0,0));//建立一个显示直方图的图片,背景为纯黑色
    int DRAW_BIN_W=cvRound(DRAW_W/histsize1);

    /****打开摄像头****/
    VideoCapture cam(0);
    if(!cam.isOpened())
        return -1;

    /****鼠标捕捉****/
    namedWindow("camera",1);
    namedWindow("rgb_hist",1);
    setMouseCallback("camera",onMouse,0);//这里用的是面向对象的思想,只要有鼠标动作就会调用鼠标响应函数

    while(1)
    {
        if(!pause)//暂停按钮只需控制视频的读取
        {        
          cam>>frame;
          if(frame.empty())
            break;   //break此处跳出的是while语句,一般是跳出for或while语句,不要理解为跳出if语句
        }

		if(tracking)
        {
            Mat RoiImage(frame,selectROI);

            /*********************************************************************************************/
            /*                                  calcHist():计算图像块的直方图矩阵            
            /*calcHist(),第1个参数为原数组区域列表;第二个参数为有计算几个原数组;参数3为需要统计的通道索引数;参数4为操作掩码
            /*第5个参数为存放目标直方图矩阵;参数6为需要计算的直方图的维数;参数7为每一维的bin的个数;参数8为每一维数值的取值范围
            /*参数10为每个bin的大小是否相同的标志,默认为1,即bin的大小都相同;参数11为直方图建立时清除内存痕迹标志,默认为0,即清除
            /**********************************************************************************************/
            calcHist(&RoiImage,1,channels,Mat(),RoiHist,3,histsize,ranges);
			//原数组区域RoiImage,1个源,需要统计的通道索引为{0,1,2},
            //目标直方图RoiHist,3维,每一维的bin数histsize,取值范围为
            //ranges,实际上计算出的目标矩阵类似一维矩阵。
                                                                            

            /****************************************************************************************/
            /*                               normalize():根据某种范数或者数值范围归一化数组         
            /* normalize(),参数1表示需要归一化的数组;参数2为归一化后的目的数组;参数3表示输出数值的最小值/最大值
            /* 或者输出数值的范数;参数4表示输出数值的最小值/最大值;参数5表示归一化数组使用的归一化类型,默认值为使用
            /*  L2范数;参数6为对应元素的掩膜矩阵,默认值为空,即不采用掩膜操作     
            /*****************************************************************************************/
            normalize(RoiHist,RoiHist);//使用L2范数将RoiHist直方图原地归一化

            vector<Mat> rgb_planes;//这里的vector为向量,向量的数据类型为Mat结构体,向量的长度为3
            split(RoiImage,rgb_planes);//将rgb图分解到rgb_planes各个分量中
            calcHist(&rgb_planes[0],1,0,Mat(),rhist,1,&histsize1,&ranges1);
            normalize(rhist,rhist,0,DRAW_H,NORM_MINMAX);//进行最大最小值归一化
            calcHist(&rgb_planes[1],1,0,Mat(),ghist,1,&histsize1,&ranges1);
            normalize(ghist,ghist,0,DRAW_H,NORM_MINMAX);
            calcHist(&rgb_planes[2],1,0,Mat(),bhist,1,&histsize1,&ranges1);
            normalize(bhist,bhist,0,DRAW_H,NORM_MINMAX);
            if(nFrame_num==1)
            {
			// preselectROI=selectROI;
                preselectROI.x=selectROI.x;
                preselectROI.y=selectROI.y;
                preselectROI.width=selectROI.width;
                preselectROI.height=selectROI.height;
                staRoiHist=RoiHist.clone();//第一次选定目标,作为标准模板目标
            }
            else if(nFrame_num>1&&comp==true)
            {
                /**************************************************************************************/
                /*                  compareHist():比较2个直方图的相似度                                    
                /* compareHist(),参数1为比较相似度的直方图1;参数2为比较相似度的直方图2;参数3为相似度的计算方式。有四种,  
                /* 分别为CV_COMP_CORREL,CV_COMP_CHISQR,CV_COMP_INTERSECT,CV_COMP_BHATTACHARYYA 
				/*************************************************************************************/
                double distence=compareHist(staRoiHist,RoiHist,CV_COMP_INTERSECT);
				//计算后面选定的与这次选定的相似度,使用INTERSECT,值越大越相似
                printf("与第1次选定的图像区域相似度为:%f\n",distence);//数组越大,相似度越大

                //显示直方图
                for(int i=1;i<histsize1;i++)
                {
                    //画直线中要注意2点,因为图片的原点在左上角,而直方图坐标系的原点在左下角,
					//所以高度值都需要被直方图图纸高度减掉,另外取一维直方图时只能用at运算符
                    line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(rhist.at<float>((i-1)))),
						Point(DRAW_BIN_W*(i),DRAW_H-cvRound(rhist.at<float>(i))),Scalar(255,0,0),2,8,0);
                    line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(ghist.at<float>((i-1)))),
						Point(DRAW_BIN_W*(i),DRAW_H-cvRound(ghist.at<float>(i))),Scalar(0,255,0),2,8,0);
                    line(draw,Point(DRAW_BIN_W*(i-1),DRAW_H-cvRound(bhist.at<float>((i-1)))),
						Point(DRAW_BIN_W*(i),DRAW_H-cvRound(bhist.at<float>(i))),Scalar(0,0,255),2,8,0);
                }
                imshow("rgb_hist",draw);
                draw=Mat::zeros(DRAW_W,DRAW_H,CV_8UC3);//每画完一次直方图后都进行一次清0操作
                comp=false;
            }
            rectangle(frame,selectROI,Scalar(0,255,0),2,8);//手动选定一次就显示一次
        }//end tracking
        rectangle(frame,preselectROI,Scalar(0,0,255),5,8);//初始的选定目标一直不变
        imshow("camera",frame);

        //键盘响应
        char c = (char)waitKey(10);
        if( c == 27 )
            break;
        switch(c)
        {
        case 'p'://暂停键
            pause = !pause;
            break;
        default:
            ;
        }
    }//end while;