例3-13设置ROI

写在前面,写的时候总有种给别人写的感觉,然后就写得很冗长,也没有办法很好的表达自己的想法,总觉得写得越多越好,实则不然,要最言简意赅,还能表达意思。

嗯!

只写自己不明白的地方,如果恰巧有人也看了我的随笔,并且有所收获那就很幸运.[如果有歧义的地方,希望可以留言讨论]

 

好了 闲言碎语不要讲了,马上开始自己的下一个笔记:

 

上一个笔记,做了一个ROI region of interest。那个采用的是opencv里面提供好的函数:

分别是cvSetImageROI() cvResetImageROI() 两个函数。

这一次依旧是设置兴趣区域,不过方法不同。

 

两种方式的区别在于,第一个只能设置一个矩阵的感兴趣区域。

而后面一个 可以设置多个感兴趣区域。

改版一:

 

#include "highgui.h"
#include "cv.h"
IplImage* src;

void funcCvSetImageROI(){
    cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 50;
    int y = 50;
    int width = 200;
    int height = 200;
    CvRect interestRect = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect.width, interestRect.height), 8, 3);
    cvSetImageROI(src, interestRect);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e3", src);
    //cvWaitKey(0);
}

void funcCvSetImageROI2(void){
    //cvNamedWindow("e4", 1);
    //src = cvLoadImage("1.png");这句话关键在上一次的结果会被保留到这一次,也就是说这次加完以后就全白了。POINT
    IplImage* subImage = cvCreateImageHeader(cvSize(200, 200), 8, 3);
    subImage->widthStep = src->widthStep;
    subImage->imageData = src->imageData + 50 * src->widthStep + 50 * src->nChannels;
    cvAddS(subImage, cvScalar(200, 160, 250, 0), subImage);
    cvShowImage("e4", src);
    cvWaitKey();
    cvDestroyAllWindows();
}
int main(){
    src = cvLoadImage("1.png");
    funcCvSetImageROI();
    funcCvSetImageROI2();
    return 0;
}

POINT

由点得到的想法是:既然可以叠加,那么是不是只用原来的函数就可以完成,多个兴趣区域的选择:

尝试:

在调用不同函数时:可以完成多个兴趣区域的选择:

void funcCvSetImageROI(){
    cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 50;
    int y = 50;
    int width = 200;
    int height = 200;
    CvRect interestRect = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect.width, interestRect.height), 8, 3);
    cvSetImageROI(src, interestRect);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e3", src);
    //cvWaitKey(0);
}
void funcCvSetImageROI_1(){
    cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 80;
    int y = 280;
    int width = 120;
    int height = 30;
    CvRect interestRect = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect.width, interestRect.height), 8, 3);
    cvSetImageROI(src, interestRect);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e5", src);
    cvWaitKey(0);
    cvDestroyAllWindows();
}

主函数顺序调用:

funcCvSetImageROI

funcCvSetImageROI_1

可显示两片区域

 

如果换一种方式:

void funcCvSetImageROI_2(){
    //cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 80;
    int y = 280;
    int width = 120;
    int height = 30;
    CvRect interestRect1 = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect1.width, interestRect1.height), 8, 3);
    cvSetImageROI(src, interestRect1);
    cvSetImageROI(src, cvRect(80, 280, 120, 30));
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e5", src);
    cvWaitKey(0);
    cvDestroyAllWindows();
}

直接调用此函数,则第一次兴趣区域丢失。

cvSetImageROI(src, interestRect1);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvSetImageROI(src, cvRect(50, 50, 200, 200));
    cvAddS(src, cvScalar(200, 160, 250, 0), src);

若如此则,全部保留。

这是因为第一次设置完兴趣区域以后,什么操作也没有做,然后就有直接设置了第二个兴趣区域,所以在加色之后,只有的后面设置的被填充粉色。所以如果后面再有兴趣区域的操作需要在设置完成之后立刻对齐进行操作。比如加色。

本段需要说明的是 图片·widthStep = 图片·width*nChannels

subImage->imageData = src->imageData + 50 * src->widthStep + 50 * src->nChannels;

子图片指针 = 原图图片的首地址+50*行占字节数【对于3通道来说,就是rgb三个字节*图片宽度表示一行,如果是单通道就是灰度值一个字节*图片宽度,完成图片从上到下的偏移量】+50*图片的通道数完成从左边到右边的偏移量

 

测试代码:

 

 

#include "highgui.h"
#include "cv.h"
IplImage* src;

void funcCvSetImageROI(){
    cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 50;
    int y = 50;
    int width = 200;
    int height = 200;
    CvRect interestRect = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect.width, interestRect.height), 8, 3);
    cvSetImageROI(src, interestRect);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e3", src);
    //cvWaitKey(0);
}
void funcCvSetImageROI_1(){
    cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 80;
    int y = 280;
    int width = 120;
    int height = 30;
    CvRect interestRect = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect.width, interestRect.height), 8, 3);
    cvSetImageROI(src, interestRect);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e5", src);
    cvWaitKey(0);
    cvDestroyAllWindows();
}
void funcCvSetImageROI_2(){
    //cvNamedWindow("e3", 1);//0是可变大小,1是固定大小且与内容适配
    int x = 80;
    int y = 280;
    int width = 120;
    int height = 30;
    CvRect interestRect1 = cvRect(x, y, width, height);
    IplImage* interestImg;
    interestImg = cvCreateImage(cvSize(interestRect1.width, interestRect1.height), 8, 3);
    cvSetImageROI(src, interestRect1);
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvSetImageROI(src, cvRect(50, 50, 200, 200));
    cvAddS(src, cvScalar(200, 160, 250, 0), src);
    cvResetImageROI(src);
    cvShowImage("e5", src);
    cvWaitKey(0);
    cvDestroyAllWindows();
}

void funcCvSetImageROI2(void){
    //cvNamedWindow("e4", 1);
    //src = cvLoadImage("1.png");这句话关键在上一次的结果会被保留到这一次,也就是说这次加完以后就全白了。
    IplImage* subImage = cvCreateImageHeader(cvSize(200, 200), 8, 3);
    subImage->widthStep = src->widthStep;
    subImage->imageData = src->imageData + 50 * src->widthStep + 50 * src->nChannels;
    cvAddS(subImage, cvScalar(200, 160, 250, 0), subImage);
    cvShowImage("e4", src);
    cvWaitKey();
    cvDestroyAllWindows();
}
int main(){
    src = cvLoadImage("1.png");
    //funcCvSetImageROI();
    funcCvSetImageROI_2();
    return 0;
}

 

学习代码:原来这个同学的blog感觉。。。并不太好。。。而且这个地方并不叫增加像素吧,虽然书上也是这么写的。。。增加对应通道的rgb数值使其完成颜色的变化或者对于单通道图片来说是灰度值的变化。。。

但我的确借鉴了。以下学习代码:以及最小可用代码片段:

#include <cv.h>  
#include <highgui.h>  

int main()
{
    IplImage* interest_img = cvLoadImage("screen.png");

    

    CvRect interest_rect = cvRect(300, 500, 200, 200);
    IplImage* sub_img = cvCreateImageHeader(cvSize(200, 200), 8, 3);

    //sub_img->origin = interest_img->origin;这个设置不设置都是一样的,可能为了适配更多的系统吧毕竟有的原点不在左上角。


    sub_img->widthStep = interest_img->widthStep;//
    //std::cout << interest_img->width;//图片的宽
    //std::cout << interest_img->widthStep;// 图片的宽*nChannels ,单通道时等于width。

    sub_img->imageData = interest_img->imageData + 500*interest_img->widthStep + 300*interest_img->nChannels;

    cvAddS(sub_img, cvScalar(50), sub_img);
    //cvShowImage("之后", sub_img);
    cvShowImage(" interest_img", interest_img);
    cvWaitKey(0);
    cvReleaseImageHeader(&sub_img);
    cvReleaseImage(&interest_img);
    return 0;
}

原来同学代码位置:

http://blog.csdn.net/shangyt/article/details/5747017

 

posted on 2016-04-22 14:46  木鸟飞  阅读(402)  评论(0编辑  收藏  举报

导航