例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

时间: 2024-10-17 00:04:24

例3-13设置ROI的相关文章

关于opencv中cv::Mat设置roi

opencv中设置roi实验: 1 cv::Mat SrcImg; 2 SrcImg = cv::imread("../resource/cpw3.png"); 3 cv::imshow("原图像",SrcImg); 4 5 // 第一次提取部分ROI 6 cv::Rect SrcImgROI = cv::Rect( SrcImg.cols/2, 0, SrcImg.cols/2, SrcImg.rows/2); 7 cv::Mat SrcROIImg = SrcI

OpenCv_Image与光流法中设置ROI区域

无论是在图片显示中或者是在光流法寻找角点的过程中,我们都会遇到ROI这个东西.它的作用就是让我们能够专注于图像或者当前视频帧中的某一块区域(我们称之为感兴趣区域) 进行处理,而不是对整个图像或者是整个视频帧进行处理,这不仅能够排除掉一些不必要的误差干扰,还能减少运算量.接下来分别说明来图像和光流法视频中如何设置ROI. 图像设置ROI 代码如下: /* * Description : setting ROI in image * Author : Liulongpo * Date : 2015年

例6.13 已知一个一维数组a[1..n](n&lt;25),又已知一整数m。 如能使数组a中任意几个

/*例6.13 已知一个一维数组a1..n,又已知一整数m. 如能使数组a中任意几个元素之和等于m,则输出YES,反之则为NO.[分析]对于一个已确定的数组a[1..n]和一个确定的数m,判断能否使数组a中任意几个元素之和等于m,等价于判断能否从数组a中取任意数使其和为m. 对于a中任意元素a[n]只有取与不取两种情况: (1)取a[n]: 则此时问题转化为:对于一个已确定的数组a[1..n-1]和一个确定的数m-a[n],判断能否使数组a[1..n-1]中任意几个元素之和等于m-a[n]. (

powerdesigner中把用例关系线设置成直线

powerdesigner中默认参与者与用例之间的关系线是折线,如图: 如果想设置成直线显示,如下图: 则需要做设置: Tools-->Display Preferences 选择最后一项 3. 选择Format 4. 点"modify",选corners中的最后一项,如图: 就ok了. 不过不知道是不是我这个版本的问题(16.5),设置完后原来的线会显示成弯线,要把原来的关系线删除掉再重新建立一次关系才会显示直线.

作业一 例3.1-3.

例3.1 class DataDemo01{ public static void main(String[] args){ int num=9999999999999999999999999; }} 例3.2 class DataDemo02{ public static void main(String[] args){ int max=2147483647; System.out.println("整型的最大值:"+max); System.out.println("整

例8.13 本例用于演示挂起和恢复!

// 本例用于演示挂起和恢复!class E13{ public static void main(String args[]) { A a=new A(); Thread thread=new Thread(a); thread.setName("zhang san"); thread.start(); while(a.getStop()==false){} System.out.println("我是主线程,负责恢复"+thread.getName()+&quo

iOS开发项目篇—13标题栏设置

iOS开发项目篇—13标题栏设置 一.添加标题栏 代码: 1 #import "YYHomeTableViewController.h" 2 #import "YYOneViewController.h" 3 4 @interface YYHomeTableViewController () 5 6 @end 7 8 @implementation YYHomeTableViewController 9 10 - (id)initWithStyle:(UITable

开源资产管理软件-GLPI(9.13)操作手册

1.简介 GLPI是法语Gestionnaire libre de parc informatique的缩写,是一款历史悠久的资产管理软件: GLPI提供功能全面的IT资源管理接口,可以用来建立数据库全面管理IT的电脑,显示器,服务器,打印机,网络设备,电话,甚至硒鼓和墨盒等.提供Helpdesk用户支持平台:联系人,合同,合作商,以及文档的管理:提供资源预定,知识库的管理等功能." 日常工作中偶然接触到GLPI,通过安装部署,配置LDAP,Fusioninventory,OCS Invento

Linux 权限设置

一.文件和目录权限 在Linux系统中,用户可以对每一个文件或目录都具有访问权限,这些访问权限决定了谁能访问,以及如何访问这些文件和目录. 1.文件权限简介 在Linux系统中,每一位用户都有对文件或目录的读取.写入和执行权限.第1套权限控制访问自己的文件权限,即所有者权限.第2套权限控制用户组访问其中一个用户的文件的权限.第3套权限控制其他所有用户访问一个用户的文件的权限.这3套权限赋予用户不同类型(即所有者.用户组和其他用户)的读取.写入及执行权限. 2.一般权限 用"ls -l"