当前位置:   article > 正文

C++ opencv小试7_opencv面试题

opencv面试题

上文提到的是边界检测与直线圆等的检测,有时候要求输入为灰度图,其实这是不影响彩图的,只要将得到边界的图有值的点认为是边界,然后在彩图上,将这些点保留,其他置为零即可。

问题17:关于remap

         这是一个像素点操作的函数,支持多维,虽然我们可以通过逐点访问来完成,这个函数其实也挺麻烦的,要自己建立映射矩阵,所以还是直接遍历吗,那样我们的可控性要比这强多了,如上下颠倒:

        #include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
void main()
{    
    int i,j;
    Mat_<Vec3f> f;
    Mat_<Vec3f> f1;
    string image_name="../Lena.jpg";
    f=imread(image_name,CV_LOAD_IMAGE_COLOR);
    if (f.empty())
    {
        cout<<"failed"<<endl;
        return;
    }
    f1.create(f.rows,f.cols);
    for(i=0;i<f.rows;i++)
        for(j=0;j<f.cols;j++)
        {
            f1(i,j)[0]=f(f.rows-1-i,j)[0];
            f1(i,j)[1]=f(f.rows-1-i,j)[1];
            f1(i,j)[2]=f(f.rows-1-i,j)[2];
        }
    normalize(f1,f1,0,1,CV_MINMAX);
    namedWindow("1",1);
    imshow("1",f1);
    waitKey(0);  
}

  涉及放大与缩小的话,可能要考虑奇数与偶数,扩展一个边界就可以了!

问题18:仿射变换,这种变换看起来很汗

        自己逐个遍历计算的话,可能会显得有些复杂,还好opencv集成了一个这个的变换函数,包括旋转等很好用;

  对一副图的旋转:#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
void main()
{    
    int i,j;
    Mat_<Vec3f> f;
    Mat_<float> f1;
    string image_name="../Lena.jpg";
    f=imread(image_name,CV_LOAD_IMAGE_COLOR);
    if (f.empty())
    {
        cout<<"failed"<<endl;
        return;
    }
    f1=getRotationMatrix2D(Point(f.rows/2,f.cols/2),-50,1);
    cout<<f1<<endl;
    warpAffine(f,f,f1,Size(1000,1000));
    normalize(f,f,0,1,CV_MINMAX);
    namedWindow("1",1);
    imshow("1",f);
    cout<<f.rows<<endl<<f.cols<<endl;
    waitKey(0);
}
    f1=getRotationMatrix2D(Point(f.rows/2,f.cols/2),-50,1);这是得到变换矩阵,参数是旋转图像的中心Point类型,第二个是角度double的,负的表示顺时针,第三个是旋转后的图像缩放,因为旋转后,有些地方就超出原图了(这你即使建立了大的1000*1000的也没有,因为它左边和上边超出了),所以缩一下比较好,0.7什么的 挺合适的。朋友们可以实践一下,   warpAffine(f,f,f1,Size(1000,1000));根据变换矩阵,得出新图,后面还有些参数,边界类型等,就默认0了,选4也可以。

   注意到warpAffine根据输入变换矩阵的不同,可以有不同的作用,旋转只是一类,我来玩仿射(就是你定义原图的3个点,映射到目标图的3个点),

 int i,j;
    Mat_<Vec3f> f;
    Mat_<float> f1;
    string image_name="../Lena.jpg";
    f=imread(image_name,CV_LOAD_IMAGE_COLOR);
    if (f.empty())
    {
        cout<<"failed"<<endl;
        return;
    }
    vector<Point2f> src;
    vector<Point2f> dst;
    src.resize(3);
    dst.resize(3);
    src[0]=Point2f(0,0);
    src[1]=Point2f(0,f.cols-1);
    src[2]=Point2f(f.rows-1,0);
    dst[0]=Point2f(0,f.cols/2);
    dst[1]=Point2f(f.rows/2,f.cols-1);
    dst[2]=Point2f(f.rows/2,0);
    f1=getAffineTransform(src,dst);
    warpAffine(f,f,f1,f.size());
    normalize(f,f,0,1,CV_MINMAX);
    namedWindow("1",1);
    imshow("1",f);
    cout<<f.rows<<endl<<f.cols<<endl;
    waitKey(0);

}
这里要注意的是必须使用Point2f类型,不能使用Point,因为getAffineTransform(src,dst);这个函数的定义是这样的,Point是2维上的整数点,Point2f坐标可以浮点,Point3f,3维的坐标点。应该不难理解;

问题19:直方图的均衡化,显然这是对灰度图的,也就是一维的,彩图的话3维图的话可以考虑分成3个一维的,处理后在合并,由于彩图我没有素材,只实验一维的灰度图了

     一维的情形#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
void main()
{    
    Mat_<Vec3b> f;
    Mat_<uchar> f1;
    Mat_<uchar> f2;
    string image_name="../1.bmp";
    f=imread(image_name,CV_LOAD_IMAGE_COLOR);
    if (f.empty())
    {
        cout<<"failed"<<endl;
        return;
    }
    cvtColor(f,f1,CV_BGR2GRAY);
    //normalize(f1,f1,0,1,CV_MINMAX);
    equalizeHist(f1,f2);
    namedWindow("1",1);
    imshow("1",f);
    namedWindow("2",1);
    imshow("2",f2);
    waitKey(0);
}

函数要求类型必须是uchar类型的,输出的竟然也是uchar类型的。

问题20:直方图的计算

       计算方法十分的简单,但是opencv的函数由于应用度的扩展,使得函数显得很复杂,其实我可以将其简单化,就是计算一个通道的直方图,其他问题其实也可以转化成这个问题来进行计算

#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
void main()
{    
    int i,j;
    float sum(0);
    double na;
    Mat_<Vec3f> image;
    Mat_<float> r_hist;
    Mat_<float> i_hist;
    Mat_<Vec3f> hist;
    Mat_<uchar> mask;
    Mat_<uchar> spemask;
    vector<Mat_<float> > planes;
    string image_name("../3.jpg");
    image=imread(image_name,CV_LOAD_IMAGE_COLOR);
    split(image,planes);
    mask.create(image.rows,image.cols);
    mask.setTo(0);
    //spemask=mask(Rect(0,0,2,2));
    spemask=mask(Range(0,2),Range(0,2));
    spemask.setTo(1);
    int histsize=255;
    float range[]={0,255};
    const float *hrange[]={range};
    calcHist(&planes[0],1,0,mask,r_hist,1,&histsize,hrange);
    for(i=0;i<r_hist.rows;i++)
        for(j=0;j<r_hist.cols;j++)
        {
            sum+=r_hist(i,j);
        }
        cout<<sum<<endl;
    hist.create(456,456);
    hist.setTo(Scalar(0,0,0));
    normalize(r_hist,r_hist,0,hist.rows,CV_MINMAX);
    i_hist=r_hist;
    na=((double)hist.cols)/histsize;
    for(i=0;i<i_hist.rows;i++)
        {
            rectangle(hist,Point((int)(i*na),hist.rows-i_hist(i,0)),Point((int)((i+1)*na),hist.rows),Scalar(1,0,0));
        }
    namedWindow("1",1);
    imshow("1",hist);
    waitKey(0);
};
  

calcHist(&planes[1],1,0,mask,r_hist,1,&histsize,hrange,true,true);这个函数,输入我们定为1维的,所以第2个写1,第3个写0,mask用来确定计算的范围,那些用于,注意实例中包括0,0点 但是不包括2,2的行与列,所以只有4个点,也要注意Rect是列在前面的,它的参数非常有意思,前面2个是左上点(包含),后面2个参数是矩形的列数,与行数,而不是顶点了。这在前面的傅里叶变换中也有用到,其他的ROI有Range的方法,它规定了行的范围,与列的范围,右下的全部不包含,可以试一试。

接下来是存储的空间,我们用1维的float,然后1维,然后是最终bins的数目,也是最后向量的长度大小,hrange是范围,各个bin由范围与数目相除可得。最后一个true是可能计算多次的话,清不清空原先的,true表示叠加,一般都是flase,最后向量中的值是个子区间的数目,要转化为0-1,可值总数像素数即可。

问题21:找出矩阵中的最大值与最小值

void main()
{    
    int i,j;
    double min,max;
    Mat_<Vec4b> f;
    f.create(3,3);
    for(i=0;i<f.rows;i++)
        for (j=0;j<f.cols;j++)
        {
            f(i,j)[0]=i+j;
            f(i,j)[1]=i+j+1;
            f(i,j)[2]=i+j+2;
        }
    f(0,0)=255;
     minMaxLoc(f,&min,&max);
     cout<<min<<endl;
     cout<<max<<endl;
}

支持多维,非常实用。

问题22:颜色空间的转换从BGR到HSV

    Mat_<Vec3f> f;
    string image_name("../Lena.jpg");
    f=imread(image_name);
    if (f.empty())
    {
        cout<<"failed"<<endl;
        return;
    }
    cvtColor(f,f,CV_BGR2HSV);
    cout<<f(1,2)[0]<<endl;
    cout<<f(1,2)[1]<<endl;
    cout<<f(1,2)[2]<<endl;
    cout<<224.0/255<<endl;

这个函数对于类型是有重载的,根据输入图像类型的不同,输出的值的范围也不同,由于我们认为H为0到360 ,H与V都是0到1;当输入是浮点数的情况下,得到的H是0-360;S是0-1,V是0-255 ,所以最后最好对V进行一个除以255的归一化,若输入BGR的图是归一化的浮点图(0-1),则得到的结果就是与我们预期的不要归一化了!HSV模型空间分为色相,纯度,最后一个V与HSI中的I还是不太一样的,但H与S确实运用的十分的广泛。若将转换后的HSV的V归一化了 则转换回去的浮点图就会归一化到(0-1)了。对于灰度图,H与S都是都是0,V的值就是灰度值。

问题23:直方图的对比

          直方图是像素大小的分布信息,opencv内置了2副 图的直方图对比方法,但是直方图的对比是很不可靠地,怎么去更好的对比直方图是一个十分重要的问题,因为有时候,不同图的直方图相差比较大,但是他们确实是相似的。函数内置了4种直方图对比方法。我们可以来试试。


#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;    
void main()
    {    
        vector<double> result;
        int i,num(0);
        float sum(0);
        Mat_<Vec3f> image;
        Mat_<Vec3f> image1;
        Mat_<float>hist;
        vector<Mat_<float> >hist_array;
        Mat_<uchar> mask;
        vector<Mat_<float> > planes;
        vector<Mat_<float> > planes1;
        string image_name("../a.jpg");
        image=imread(image_name,CV_LOAD_IMAGE_COLOR);
        image_name="../c.jpg";
        image1=imread(image_name,CV_LOAD_IMAGE_COLOR);
        //cout<<image1(1,2)[0]<<image1(1,2)[1]<<image1(1,2)[2]<<endl;
        cvtColor(image,image,CV_BGR2HSV);
        cvtColor(image1,image1,CV_BGR2HSV);
        split(image,planes);
        split(image1,planes1);
        int histsize=180;
        float range[]={0,360};
        const float *hrange[]={range};
        int histsize1=100;
        float range1[]={0,1};
        const float *hrange1[]={range1};
        for(i=0;i<1;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize,hrange);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize,hrange);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        for(i=1;i<3;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        result.push_back(compareHist(hist_array[3],hist_array[2],0));
        cout<<result[0]<<endl;
        waitKey(0);
}

这段比较有意思的问题一个是hist的指向问题,它竟然是原空间的改变,所以必须要clone才行,十分奇怪。还有得到的hist是1列的,很多行的!

calcHist的一个作用是帮助我们进行任何矩阵的直方图均衡化,因为已经得到了分布的信息。直方图的对比方法是不如人意的。特征的提取十分重要,

特征的对比方法也非常重要。好的对比方法可以应对非常多的异化。

Mat_<uchar> f;
        Mat_<uchar> f1;
        f.create(2,2);
        f1=f;
        f.create(2,2);
        f(1,1)=3;
        cout<<f<<endl;这里是相同大小的creat,则是在原始空间的。不相同大小则是另辟空间。

问题24:反向投影,这也就是说根据一个计算好的直方图,一般最大的bin映射到255,用calcBackProject计算:得到输入的像素在哪一个bin里,然后把这个像素值转化为前面bin映射的值。可以这么理解:一大块像素相同分布的图,那么这块bin的肯定映射到很大,那么如果输入的图像的值如果在这个bin内,那么它的转化值就会大,这样就把这块图标记出来了,显然原图与输入图Range最好相同.

wenti25:我们对前面的知识进行一些补充与实验

           Mat_<float> f;
        Mat_<float> hist;
        Mat_<uchar> mask;
        int i,j;
        int histsize[]={5};
        int channel[]={0};
        float range[]={0,5};
        const float *hrange[]={range};
        
        f.create(3,3);
        for(i=0;i<f.rows;i++)
            for (j=0;j<f.cols;j++)
            {
                f(i,j)=i+j;
            }
        cout<<f<<endl;
        calcHist(&f,1,channel,mask,hist,1,histsize,hrange);
        cout<<hist<<endl;


左包含的,若在所以前面的255改为256个 范围为0-256比较好,比最大值大一些;

int histsize[]={4};
        int channel[]={0};
        float range[]={2,4};这样的话  shi [2 2.5)   [2.5 3)  [3 3.5)  [3.5 4)显然4的点未统计进去,矩阵中的一些值也未统计进去(图像数据知识矩阵数据的一小部分而已)。

#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;    
void main()
    {    
        /*vector<double> result;
        int i,num(0);
        float sum(0);
        Mat_<Vec3f> image;
        Mat_<Vec3f> image1;
        Mat_<float> hist;
        Mat_<float> hist1;
        vector<Mat_<float> >hist_array;
        Mat_<uchar> mask;
        vector<Mat_<float> > planes;
        vector<Mat_<float> > planes1;
        string image_name("../a.jpg");
        image=imread(image_name,CV_LOAD_IMAGE_COLOR);
        image_name="../c.jpg";
        image1=imread(image_name,CV_LOAD_IMAGE_COLOR);
        //cout<<image1(1,2)[0]<<image1(1,2)[1]<<image1(1,2)[2]<<endl;
        cvtColor(image,image,CV_BGR2HSV);
        cvtColor(image1,image1,CV_BGR2HSV);
        split(image,planes);
        split(image1,planes1);
        int histsize=180;
        float range[]={0,360};
        const float *hrange[]={range};
        int histsize1=100;
        float range1[]={0,1};
        const float *hrange1[]={range1};
        for(i=0;i<1;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize,hrange);
            hist1=hist.clone();
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize,hrange);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        for(i=1;i<3;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        result.push_back(compareHist(hist_array[0],hist_array[0],1));
        cout<<result[0]<<endl;
        waitKey(0);*/
        Mat_<Vec2f> f;
        Mat_<float> hist;
        Mat_<uchar> mask;
        int i,j;
        int histsize[]={5,4};
        int channel[]={0,1};
        float range[]={0,5};
        float range1[]={0,5};
        const float *hrange[]={range,range1};
        f.create(3,3);
        for(i=0;i<f.rows;i++)
            for (j=0;j<f.cols;j++)
            {
                f(i,j)[0]=i+j;
                f(i,j)[1]=i+j;
            }
        cout<<f<<endl;
        calcHist(&f,1,channel,mask,hist,2,histsize,hrange);
        cout<<hist<<endl;
        cout<<hist.size()<<endl;
        cout<<hist.rows<<endl<<hist.cols<<endl;
}

这是多维的统计情形,它把多个通道的点对应成某一维度的点,然后统计各个坐标在各个范围上的计数情况。主要hist定义要成为一维的float 十分奇怪。

#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;    
void main()
    {    
        /*vector<double> result;
        int i,num(0);
        float sum(0);
        Mat_<Vec3f> image;
        Mat_<Vec3f> image1;
        Mat_<float> hist;
        Mat_<float> hist1;
        vector<Mat_<float> >hist_array;
        Mat_<uchar> mask;
        vector<Mat_<float> > planes;
        vector<Mat_<float> > planes1;
        string image_name("../a.jpg");
        image=imread(image_name,CV_LOAD_IMAGE_COLOR);
        image_name="../c.jpg";
        image1=imread(image_name,CV_LOAD_IMAGE_COLOR);
        //cout<<image1(1,2)[0]<<image1(1,2)[1]<<image1(1,2)[2]<<endl;
        cvtColor(image,image,CV_BGR2HSV);
        cvtColor(image1,image1,CV_BGR2HSV);
        split(image,planes);
        split(image1,planes1);
        int histsize=180;
        float range[]={0,360};
        const float *hrange[]={range};
        int histsize1=100;
        float range1[]={0,1};
        const float *hrange1[]={range1};
        for(i=0;i<1;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize,hrange);
            hist1=hist.clone();
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize,hrange);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        for(i=1;i<3;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        result.push_back(compareHist(hist_array[0],hist_array[0],1));
        cout<<result[0]<<endl;
        waitKey(0);*/
        Mat_<Vec3f> f;
        Mat_<Vec2f> f1;
        Mat_<float> hist;
        Mat_<uchar> mask;
        int i,j;
        int histsize[]={5,5,5};
        int channel[]={0,1,2};
        float range[]={0,5};
        float range1[]={0,5};
        float range2[]={0,5};
        const float *hrange[]={range,range1,range2};
        f.create(3,3);
        for(i=0;i<f.rows;i++)
            for (j=0;j<f.cols;j++)
            {
                f(i,j)[0]=i+j;
                f(i,j)[1]=i+j;
                f(i,j)[2]=i+j;
            }
        calcHist(&f,1,channel,mask,hist,3,histsize,hrange);
        
        //cout<<hist<<endl;
        //cout<<hist.size()<<endl;
        cout<<hist(1,1,1)<<endl;
        cout<<hist.rows<<endl<<hist.cols<<endl;
}

这是对多维统计的例子,我们要注意的是hist的访问形式,这时候,hist不能输出size与rows与cols,很少特殊。

访问要hist(1,1,1)这样去访问,这是范围在[1 2)  [1 2) [1,2)点的统计。也就是说,函数可以统计多维的点。

calcHist(&f,1,channel,mask,hist,2,histsize,hrange);
        normalize(hist,hist,0,251,CV_MINMAX);
        
        //cout<<hist<<endl;
        //cout<<hist.size()<<endl;
        cout<<hist(1,1)<<endl;
        cout<<hist.rows<<endl<<hist.cols<<endl;

当hist是3维的时候,对于hist就不能用normalize函数了,所以对多维点统计最后归一化可能会比较麻烦。

#include <string>
#include <cstdio>
#include <cmath>
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;    
void main()
    {    
        /*vector<double> result;
        int i,num(0);
        float sum(0);
        Mat_<Vec3f> image;
        Mat_<Vec3f> image1;
        Mat_<float> hist;
        Mat_<float> hist1;
        vector<Mat_<float> >hist_array;
        Mat_<uchar> mask;
        vector<Mat_<float> > planes;
        vector<Mat_<float> > planes1;
        string image_name("../a.jpg");
        image=imread(image_name,CV_LOAD_IMAGE_COLOR);
        image_name="../c.jpg";
        image1=imread(image_name,CV_LOAD_IMAGE_COLOR);
        //cout<<image1(1,2)[0]<<image1(1,2)[1]<<image1(1,2)[2]<<endl;
        cvtColor(image,image,CV_BGR2HSV);
        cvtColor(image1,image1,CV_BGR2HSV);
        split(image,planes);
        split(image1,planes1);
        int histsize=180;
        float range[]={0,360};
        const float *hrange[]={range};
        int histsize1=100;
        float range1[]={0,1};
        const float *hrange1[]={range1};
        for(i=0;i<1;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize,hrange);
            hist1=hist.clone();
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize,hrange);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        for(i=1;i<3;i++)
        {
            calcHist(&planes[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
            calcHist(&planes1[i],1,0,mask,hist,1,&histsize1,hrange1);
            normalize(hist,hist,0,1,CV_MINMAX);
            hist_array.push_back(hist);
            hist_array[num++]=hist.clone();
        }
        result.push_back(compareHist(hist_array[0],hist_array[0],1));
        cout<<result[0]<<endl;
        waitKey(0);*/
        Mat_<Vec2f> f;
        Mat_<float> hist;
        Mat_<float> result;
        Mat_<uchar> mask;
        int i,j;
        int histsize[]={5,5,5};
        int channel[]={0,1};
        float range[]={0,5};
        float range1[]={0,5};
        float range2[]={0,5};
        const float *hrange[]={range,range1,range2};
        float range3[]={4,5};
        float range4[]={4,5};
        float range5[]={0,5};
        const float *hrange1[]={range3,range4,range5};
        f.create(3,3);
        for(i=0;i<f.rows;i++)
            for (j=0;j<f.cols;j++)
            {
                f(i,j)[0]=i+j;
                f(i,j)[1]=i+j;
                //f(i,j)[2]=i+j;
            }
        calcHist(&f,1,channel,mask,hist,2,histsize,hrange);
        normalize(hist,hist,0,251,CV_MINMAX);
        calcBackProject(&f,1,channel,hist,result,hrange1);
        cout<<result<<endl;
        //cout<<hist<<endl;
        //cout<<hist.size()<<endl;
        cout<<hist(1,1)<<endl;
        cout<<hist.rows<<endl<<hist.cols<<endl;
}

这是反向投影的例子,calcBackProject函数的各个参数要对应,这里channel是0,1所以是2维点的对应,hist也是对矩阵2维点的统计,result是维度点的映射,所以是一维的,后面的hrange2这里最好是与hrange相等,不相等好像会出很奇怪的差错,相等则表示,如果输入图的点有在计算出的hist的对应范围内,则该点映射为hist中对应的值,若输入点的值不在这个范围内,则该点映射为0。虽然直方图支持多维度点的统计,但是一般情况下,我们还是一维点的统计,多维度的分成各个单维度的分别统计也是分析多维的一种方法。

问题25:模板匹配(在一副大图里,找到小图对应的部分)

             Mat_<float> f;
    Mat_<float> f1;
    Mat_<float> result;
    f=imread("../s.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    f1=imread("../v.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    matchTemplate(f,f1,result, CV_TM_CCORR_NORMED);
    cout<<result.size()<<endl;
    cout<<f.size()<<endl;
    double minVal;
    double maxVal;
    Point minLoc;
    Point maxLoc,matchLoc;
    minMaxLoc(result,&minVal,&maxVal,&minLoc,&maxLoc);
    matchLoc=maxLoc;
    rectangle(f,Point(matchLoc.x, matchLoc.y), Point(matchLoc.x + f1.cols,matchLoc.y + f1.rows),Scalar::all(0));
    normalize(f,f,0,1,CV_MINMAX);
    namedWindow("1",1);
    imshow("1",f);
    waitKey(0);

基本还是能够匹配到的。CV_TM_CCOEFF_NORMED效果相对较好

支持彩图与彩图的匹配,值得注意的是 minMaxLoc返回的点的位置是Point(列,行);这样的,与rectangle(图,Point(列,行),Point(列行))刚好匹配,比较特殊!



 

   

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/554653
推荐阅读
相关标签
  

闽ICP备14008679号