user-0 提问: 有关cvSetImageROI()和cvResetImageROI()函数的困惑

回复:
user: user-1
content: cvCloneImage()函数不但会复制图像数据，而且会拷贝图像头，也就是说，会连原图像的typedef struct _IplImage结构数据，你设置了ROI，其实只是更改了原图像typedef struct _IplImage结构中中roi成员，而其他成员并没有改变，所以你克隆后的图像width和height当然会等于原图像，

user: user-2
content: 的确，因为clone的时候大概把其他参数也clone过来，建议你先根据ROI大小，Create dstimg，这样dstimg的大小就是ROI的大小了

user: user-3
content: 你应当在cvResetImageROI(img); 这一语句前输出你想要的结果

user: user-4
content: 上一页  目　录  下一页  SetImageROI     SetImageROI 基于给定的矩形设置感兴趣区域   void cvSetImageROI( IplImage* image, CvRect rect ); image  图像头.  rect  ROI 矩形.  函数 cvSetImageROI 基于给定的矩形设置图像的 ROI（感兴趣区域） . 如果ROI是NULL 并且参数RECT的值不等于整个图像, ROI被分配. 不像 COI, 大多数的 OpenCV 函数支持 ROI 并且处理它就像它是一个分离的图像 (例如, 所有的像素坐标从ROI的左上角或左下角（基于图像的结构）计算。       收录时间：2007年7月18日，15点15分 编辑时间：2007年7月18日，15点15分

user: user-5
content: cvShowImage("dst",dst); 用的是roi参数里面的值 而这个值 就是cvRect(0,0,120,120);

user: user-5
content: typedef struct CvRect {int x; /* 方形的最左角的x-坐标 */ int y; /* 方形的最上或者最下角的y-坐标 */ int width; /* 宽 */ int height; /* 高 */ }  IplImage 结构解读：  typedef struct _IplImage  {  int nSize;                    /* IplImage大小 */   int ID;                         /* 版本 (=0)*/   int nChannels;           /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */  int alphaChannel; /* 被OpenCV忽略 */  int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */  char colorModel[4]; /* 被OpenCV忽略 */  char channelSeq[4]; /* 同上 */   int dataOrder; /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道. cvCreateImage只能创建交叉存取图像 */  int origin; /* 0 - 顶—左结构,1 - 底—左结构 (Windows bitmaps 风格) */   int align; /* 图像行排列 (4 or 8). OpenCV 忽略它，使用 widthStep 代替 */  int width; /* 图像宽像素数 */   int height; /* 图像高像素数*/   struct _IplROI *roi; /* 图像感兴趣区域. 当该值非空只对该区域进行处理 */  struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */   void *imageId; /* 同上*/   struct _IplTileInfo *tileInfo; /*同上*/   int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep），单位字节*/   char *imageData; /* 指向排列的图像数据 */ int widthStep; /* 排列的图像行大小，以字节为单位 */ int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */ int BorderConst[4];   以下为网上验证  结论 cvSetImageROI(img,cvRect(0,0,120,120));  最后还有一个重要参数roi(region of interest 感兴趣的区域),这个参数是IplROI结构体类型的变量。IplROI结构体包含了xOffset,yOffset,height,width,coi成员变量，其中xOffset,yOffset是x,y坐标，coi代表channel of interest(感兴趣的通道)。有时候，OpenCV图像函数不是作用于整个图像，而是作用于图像的某一个部分。这是，我们就可以使用roi成员变量了。如果IplImage变量中设置了roi，则OpenCV函数就会使用该roi变量。如果coi被设置成非零值，则对该图像的操作就只作用于被coi指定的通道上了。不幸的是，许多OpenCV函数忽略了coi的值。  访问图像中的数据

user: user-5
content: 引用 2 楼 gaoping15106203675 的回复:我返回他们的width,height, "cout<<"img width = "<< img->width<<endl; cout<<"img height ="<< img->height<<endl; cout<<"dst width = "<<dst->width<<endl; cout<<"dst height ="<< dst->height<<endl;" 得到的结果都255,255；255,255；可是显示的图像大小却是（255,255），（120,120），不理解的就是这里，不好意思，表述不清晰。 第一 声明 我只看过很少的学习opencv 我想你也是书上的例子吧 第二 遇到问题 分析问题 解决问题 其实你也可以得 只是你没静下心来  你可以去用程序验证你的问题了 其实你已经解决了百分之80了 剩下的就是反推了 cvSetImageROI(img,cvRect(0,0,120,120)); dst = cvCloneImage(img); 第一个函数 cvSetImageROI 里面的参数cvRect(0,0,120,120) 只是改变图片的显示位置 和像素的大小 并没有改变这副图片的像素  所以cout<<"img width = "<< img->width<<endl; cout<<"img height ="<< img->height<<endl; cout<<"dst width = "<<dst->width<<endl; cout<<"dst height ="<< dst->height<<endl; 他们都是一样的  也就是说取cvResetImageROI() 只是改变img的显示位置的参数cvRect 这是一种类型 你按f12 查看 或者百度查看，这个函数并不改变图片的本身  推理完毕 按道理讲 没有第二种解释 会比我这个好 所以我的回答是正确的  我也是新手 只不过接触了2天opencv 剩下的就是你自己的逻辑分析 以结果 分析结果

user: user-0
content: 我返回他们的width,height, "cout<<"img width = "<< img->width<<endl; cout<<"img height ="<< img->height<<endl; cout<<"dst width = "<<dst->width<<endl; cout<<"dst height ="<< dst->height<<endl;" 得到的结果都255,255；255,255；可是显示的图像大小却是（255,255），（120,120），不理解的就是这里，不好意思，表述不清晰。

user: user-5
content: 虽然我很想回答你这个opencv的问题 但是我没看懂你的问题问的是什么 获取两图像的width和height，却是一样大小 是什么意思 啊 你那个分明就不是一样大小的啊 不是获取原图的某部分区域吗 从 0 0开始120 120像素吗 你还想要多大的啊