【练习3.5】使用感兴趣区域(ROI)

2014-05-29

第三章 初探OpenCV

练习第5题:

题目:学习使用感兴趣区域(ROI)。创建一个210*210的单通道图像并将其归0。在图中使用ROI和cvSet建立一个增长如金字塔状的数组,也就是:外部边界为0,下一个内部边界应该为20,在下一个内部边界为40,依此类推,直到最后内部值为200,所有边界应该为10个像素宽度。最后显示这个图形。

按照题目要求使用ROI和cvSet实现 

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

void DrawHandler(IplImage * img, CvPoint PtLT,CvPoint PtRB,int EW);

void DrawLayer(IplImage * img,int IWidth,int IHeight,int EDistance,int EWidth);

int main( int argc, char** argv )
{    
    //为实现模块化,程序只需给出四个条件:图像、图像Width和Height、边距、边宽

    IplImage* single_img = cvCreateImage(cvSize(210, 210), 8, 1);//210*210 单通道
    cvZero(single_img);
    int imgWidth = 210, imgHeight = 210;
    int EdgeDistance=20;
    int EdgeWidth=10;

    DrawLayer(single_img,imgWidth,imgHeight,EdgeDistance,EdgeWidth);
    
    cvNamedWindow("ROI", 0);
    cvShowImage("ROI", single_img);

    cvWaitKey(0);
    cvDestroyWindow("ROI");
    cvReleaseImage(&single_img);

    /*system("pause");*/
}

void DrawLayer(IplImage * img,int IWidth,int IHeight,int EDistance,int EWidth)
{
    CvPoint LTPoint=cvPoint(0,0),RBPoint=cvPoint(IWidth,IHeight);//LTPoint:LeftTopPoint
    for(int i=0;i<=IWidth-EWidth;i+=EDistance)
    {
        //调用画图函数
        DrawHandler(img,LTPoint,RBPoint,EWidth);

        LTPoint.x+=EDistance;
        LTPoint.y+=EDistance;        
    }
}

void DrawHandler(IplImage * img, CvPoint PtLT,CvPoint PtRB,int EW)
{        
    int RectWidth,RectHeight;
    RectWidth=PtRB.x-PtLT.x;
    RectHeight=EW;
    CvRect RectROI=cvRect(PtLT.x,PtLT.y,RectWidth,RectHeight);
    cvSetImageROI(img,RectROI);
    cvSet(img,cvScalar(255));
    cvResetImageROI(img);

    //设置第二次ROI的时候,去掉与上面兴趣区域重叠的部分
    RectWidth=EW;
    RectHeight=PtRB.y-PtLT.y-EW;
    if(RectHeight!=0)
    {
        RectROI=cvRect(PtLT.x,PtLT.y+EW,RectWidth,RectHeight);
        cvSetImageROI(img,RectROI);
        cvSet(img,cvScalar(255));
        cvResetImageROI(img);
    }    
}

运行结果:

 

根据这个题目拓展,使用ROI构造金字塔图形:使用ROI和画矩形的函数实现

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

void DrawHandler(IplImage * img, CvPoint PtLT,CvPoint PtRB,int EW);

void DrawLayer(IplImage * img,int IWidth,int IHeight,int EDistance,int EWidth);

int main( int argc, char** argv )
{    
    //为实现模块化,程序只需给出四个条件:图像、图像Width和Height、边距、边宽,

    IplImage* single_img = cvCreateImage(cvSize(210, 210), 8, 1);//210*210 单通道
    cvZero(single_img);
    int imgWidth = 210, imgHeight = 210;
    int EdgeDistance=20;
    int EdgeWidth=10;

    DrawLayer(single_img,imgWidth,imgHeight,EdgeDistance,EdgeWidth);
    
    cvNamedWindow("ROI", 0);
    cvShowImage("ROI", single_img);

    cvWaitKey(0);
    cvDestroyWindow("ROI");
    cvReleaseImage(&single_img);

    /*system("pause");*/
}

void DrawLayer(IplImage * img,int IWidth,int IHeight,int EDistance,int EWidth)
{
    CvPoint LTPoint=cvPoint(0,0),RBPoint=cvPoint(IWidth,IHeight);//LTPoint:LeftTopPoint
    for(int i=IWidth;i>=IWidth/2;i-=EDistance)
    {
        //调用画图函数
        DrawHandler(img,LTPoint,RBPoint,EWidth);

        LTPoint.x+=EDistance;
        LTPoint.y+=EDistance;
        RBPoint.x-=EDistance;
        RBPoint.y-=EDistance;
    }
}

void DrawHandler(IplImage * img, CvPoint PtLT,CvPoint PtRB,int EW)
{    
    CvRect RectROI=cvRect(PtLT.x,PtLT.y,PtRB.x-PtLT.x,PtRB.y-PtLT.y);
    
    cvSetImageROI(img,RectROI);

    //如果使用ROI的话,画矩形的时候,第一个矩形的左上角和右下角总是ROI的左上角和右下角,

    CvPoint RectLTP=cvPoint(0,0),RectRBP=cvPoint(RectROI.width  ,RectROI.height );

    for(int i=1;i<=EW;++i)
    {                
        cvRectangle(img,RectLTP,RectRBP,cvScalar(255));

        RectLTP.x++;
        RectLTP.y++;
        RectRBP.x--;
        RectRBP.y--;
    }

    cvResetImageROI(img);
}

 结果图形:

posted on 2014-07-18 17:28  毋忆典藏  阅读(615)  评论(0编辑  收藏  举报