uiimageview旋转180 iplimage 转化后为什么旋转了

iOS 问题:怎么把一个UIImageView对象旋转90度,然后储存为新的imageview对象?后面有个函数需要这个对象作为参数 -
怎么把一个UIImageView对象旋转90度,然后储存为新的imageview对象?后面有个函数需要这个对象作为参数
共有 2 个回答
UIImageView旋转
UIImageView *_weiboContentTextV
_weiboContentTextView.transform=CGAffineTransformMakeRotation(CGFloat angle);传入弧度值
弧度值为:角度**M_PI/180
登录后方可回复
登录后方可回复
登录后方可回答[iOS OpenCV的使用,灰度和二值化]
时间: 17:46:44
&&&& 阅读:1084
&&&& 评论:
&&&& 收藏:0
标签:看网上方法很多,但版本都不够新,我看了网上一些知识,总结了下,来个最新版Xcode6.1的.
最近主要想做iOS端的车牌识别,所以开始了解OpenCV。有兴趣的可以跟我交流下哈。
一.Opencv的使用:
  步骤:
  1.从官网下载iOS版本的Opencv2.framework。
  2.拖进工程,选择copy items if needed
  3.进入building settings,设置Framework SearchPath:
     设置成$(PROJECT_DIR)/Newtest,这个Newtest是你的项目名,主要是为了定位到你存放的Opencv2.framework所在位置。
  4.使用Opencv的方式:第(1)种全局pch:(不推荐)新建pch文件,修改成:
              #ifdef __cplusplus
              #import &opencv2/opencv.hpp&
              #endif
               &并在building setting里的 Incease Sharing of Precompiled Headers项目处:
               设置成$(PROJECT_DIR)/Newtest,同理,这个Newtest是你的项目名,主要是为了定位到你存放的PCH文件所在位置。
              PCH文件以前建工程默认生成,是全局性质的import。Xcode6不再自动生成。苹果引导开发者在某个类要用时才用。
             第(2)种:在需要的地方#import &opencv2/opencv.hpp&
                这里的重点是:使用opencv的类名一定要改成.mm!!
            & & & & & & 比如你专门写了各一个处理图片的类,Imageprocess。可以在.h里加入。
二:灰度化和二值化的主要实现过程:
  其实过程就是这样:
  UIImage(iOS图像类)-& cv::Mat(OpenCV图像类) -& Opencv灰度或二值处理函数 -& UIImage
三:Opencv类Imageprocess代码参考:
Imageprocess.h
Imageprocess.h
Chepaishibie
Created by shen on 15/1/28.
Copyright (c) 2015年 shen. All rights reserved.
#import &Foundation/Foundation.h&
#import &opencv2/opencv.hpp&
#import &UIKit/UIKit.h&
@interface Imageprocess : UIViewController
- (cv::Mat)cvMatFromUIImage:(UIImage *)
- (UIImage *)UIImageFromCVMat:(cv::Mat)cvM
- (IplImage *)CreateIplImageFromUIImage:(UIImage *)
- (UIImage *)UIImageFromIplImage:(IplImage *)
- (UIImage *)Grayimage:(UIImage *)
- (UIImage *)Erzhiimage:(UIImage *)
Otsu(unsigned char* pGrayImg , int iWidth , int iHeight);
Imageprocess.mm 里面包含了很多函数:
主要是 UIImage-&cv::Mat ,cv::Mat-&UIImage,UIImage-&IplImage,IplImage-&UIImage,&灰度化,二值化等,还有个OSTU计算阈值的方法。
Imageprocess.mm
Chepaishibie
Created by shen on 15/1/28.
Copyright (c) 2015年 shen. All rights reserved.
#import "Imageprocess.h"
@implementation Imageprocess
#pragma mark - opencv method
// UIImage to cvMat
- (cv::Mat)cvMatFromUIImage:(UIImage *)image
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
CGFloat cols = image.size.
CGFloat rows = image.size.
cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,
// Pointer to
// Width of bitmap
// Height of bitmap
// Bits per component
cvMat.step[0],
// Bytes per row
colorSpace,
// Colorspace
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrderDefault); // Bitmap info flags
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
return cvM
// CvMat to UIImage
-(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorS
if (cvMat.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
colorSpace = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(cvMat.cols,
cvMat.rows,
//bits per component
8 * cvMat.elemSize(),
//bits per pixel
cvMat.step[0],
//bytesPerRow
colorSpace,
//colorspace
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
//CGDataProviderRef
//should interpolate
kCGRenderingIntentDefault
// Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return finalI
//由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构。
// NOTE you SHOULD cvReleaseImage() for the return value when end of the code.
- (IplImage *)CreateIplImageFromUIImage:(UIImage *)image {
// Getting CGImage from UIImage
CGImageRef imageRef = image.CGI
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Creating temporal IplImage for drawing
IplImage *iplimage = cvCreateImage(
cvSize(image.size.width,image.size.height), IPL_DEPTH_8U, 4
// Creating CGContext for temporal IplImage
CGContextRef contextRef = CGBitmapContextCreate(
iplimage-&imageData, iplimage-&width, iplimage-&height,
iplimage-&depth, iplimage-&widthStep,
colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault
// Drawing CGImage to CGContext
CGContextDrawImage(
contextRef,
CGRectMake(0, 0, image.size.width, image.size.height),
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
// Creating result IplImage
IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 3);
cvCvtColor(iplimage, ret, CV_RGBA2BGR);
cvReleaseImage(&iplimage);
// NOTE You should convert color mode as RGB before passing to this function
- (UIImage *)UIImageFromIplImage:(IplImage *)image {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Allocating the buffer for CGImage
NSData *data =
[NSData dataWithBytes:image-&imageData length:image-&imageSize];
CGDataProviderRef provider =
CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
// Creating CGImage from chunk of IplImage
CGImageRef imageRef = CGImageCreate(
image-&width, image-&height,
image-&depth, image-&depth * image-&nChannels, image-&widthStep,
colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault,
provider, NULL, false, kCGRenderingIntentDefault
// Getting UIImage from CGImage
UIImage *ret = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
#pragma mark - custom method
// OSTU算法求出阈值
Otsu(unsigned char* pGrayImg , int iWidth , int iHeight)
if((pGrayImg==0)||(iWidth&=0)||(iHeight&=0))return -1;
int ihist[256];
int thresholdValue=0; // &&&&
int n, n1, n2 ;
double m1, m2, sum, csum, fmax,
int i,j,k;
memset(ihist, 0, sizeof(ihist));
n=iHeight*iW
sum = csum = 0.0;
fmax = -1.0;
for(i=0; i & iH i++)
for(j=0; j & iW j++)
ihist[*pGrayImg]++;
pGrayImg++;
pGrayImg -=
for (k=0; k &= 255; k++)
sum += (double) k * (double) ihist[k];
for (k=0; k &=255; k++)
n1 += ihist[k];
if(n1==0)continue;
n2 = n - n1;
if(n2==0)break;
csum += (double)k *ihist[k];
m1 = csum/n1;
m2 = (sum-csum)/n2;
sb = (double) n1 *(double) n2 *(m1 - m2) * (m1 - m2);
if (sb & fmax)
thresholdValue =
return(thresholdValue);
-(UIImage *)Grayimage:(UIImage *)srcimage{
//openCV二值化过程:
//1.Src的UIImage -&
Src的IplImage
IplImage* srcImage1 = [self CreateIplImageFromUIImage:srcimage];
//2.设置Src的IplImage的ImageROI
int width = srcImage1-&
int height = srcImage1-&
printf("图片大小%d,%d\n",width,height);
// 分割矩形区域
int x = 400;
int y = 1100;
int w = 1200;
int h = 600;
//cvSetImageROI:基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvSetImageROI(srcImage1, cvRect(x, y, w , h));
//3.创建新的dstImage1的IplImage,并复制Src的IplImage
IplImage* dstImage1 = cvCreateImage(cvSize(w, h), srcImage1-&depth, srcImage1-&nChannels);
//cvCopy:如果输入输出数组中的一个是IplImage类型的话,其ROI和COI将被使用。
cvCopy(srcImage1, dstImage1,0);
//cvResetImageROI:释放基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvResetImageROI(srcImage1);
resimage = [self UIImageFromIplImage:dstImage1];
//4.dstImage1的IplImage转换成cvMat形式的matImage
cv::Mat matImage = [self cvMatFromUIImage:srcimage];
cv::Mat matG
//5.cvtColor函数对matImage进行灰度处理
//取得IplImage形式的灰度图像
cv::cvtColor(matImage, matGrey, CV_BGR2GRAY);// 转换成灰色
//6.使用灰度后的IplImage形式图像,用OSTU算法算阈值:threshold
//IplImage grey = matG
resimage = [self UIImageFromCVMat:matGrey];
unsigned char* dataImage = (unsigned char*)grey.imageD
int threshold = Otsu(dataImage, grey.width, grey.height);
printf("阈值:%d\n",threshold);
//7.利用阈值算得新的cvMat形式的图像
cv::Mat matB
cv::threshold(matGrey, matBinary, threshold, 255, cv::THRESH_BINARY);
//8.cvMat形式的图像转UIImage
UIImage* image = [[UIImage alloc ]init];
image = [self UIImageFromCVMat:matBinary];
resimage =
-(UIImage *)Erzhiimage:(UIImage *)srcimage{
//openCV二值化过程:
//1.Src的UIImage -&
Src的IplImage
IplImage* srcImage1 = [self CreateIplImageFromUIImage:srcimage];
//2.设置Src的IplImage的ImageROI
int width = srcImage1-&
int height = srcImage1-&
printf("图片大小%d,%d\n",width,height);
// 分割矩形区域
int x = 400;
int y = 1100;
int w = 1200;
int h = 600;
//cvSetImageROI:基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvSetImageROI(srcImage1, cvRect(x, y, w , h));
//3.创建新的dstImage1的IplImage,并复制Src的IplImage
IplImage* dstImage1 = cvCreateImage(cvSize(w, h), srcImage1-&depth, srcImage1-&nChannels);
//cvCopy:如果输入输出数组中的一个是IplImage类型的话,其ROI和COI将被使用。
cvCopy(srcImage1, dstImage1,0);
//cvResetImageROI:释放基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvResetImageROI(srcImage1);
resimage = [self UIImageFromIplImage:dstImage1];
//4.dstImage1的IplImage转换成cvMat形式的matImage
cv::Mat matImage = [self cvMatFromUIImage:srcimage];
cv::Mat matG
//5.cvtColor函数对matImage进行灰度处理
//取得IplImage形式的灰度图像
cv::cvtColor(matImage, matGrey, CV_BGR2GRAY);// 转换成灰色
//6.使用灰度后的IplImage形式图像,用OSTU算法算阈值:threshold
IplImage grey = matG
unsigned char* dataImage = (unsigned char*)grey.imageD
int threshold = Otsu(dataImage, grey.width, grey.height);
printf("阈值:%d\n",threshold);
//7.利用阈值算得新的cvMat形式的图像
cv::Mat matB
cv::threshold(matGrey, matBinary, threshold, 255, cv::THRESH_BINARY);
//8.cvMat形式的图像转UIImage
UIImage* image = [[UIImage alloc ]init];
image = [self UIImageFromCVMat:matBinary];
resimage =
四:可能问题:
  1.出现‘list‘ file not found: & 检查类名是否改成.mm了!还不行的话,在Build Phases 中加入库:libc++.dylib 试试。
  2.arm64不支持的问题:在Building settings里Build Active Architecture Only改为No,然后下面Valid&Architectures把arm64删了。
五:样例参考:有两个很好的例子,一个是二值,一个是图像匹配。
1.二值&/zltqzj/ios_opencv_divide
2.图像匹配&/jimple/OpenCVSample
&&国之画&&&& &&
版权所有 京ICP备号-2
迷上了代码!技术(16)
PS,我在实验中发现,至少是在ios中,cvLoadImage保存文件时,bmp可以,但是jpg就不行,貌似只能保存源数据,不能是编解码以后的,以后再说,今天先记在这里。。。
本文转自/fzzl/archive//1512022.html
,感谢原作者分享!
由 于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构。IplImage结构来源于Intel的另外 一个函数库Intel Image Processing Library (IPL),该函数库主要是针对图像处理。IplImage结构具体定义如下:
typedef struct _IplImage
&&&&&&& int nS&&&&&&&& /* IplImage大小 */
&&&&&&& int ID;&&&&&&&&&&& /*&版本 (=0)*/
&&&&&&& int nC&&&& /*&大多数OPENCV函数支持1,2,3 或 4 个通道 */
&&&&&&& int alphaC /*&被OpenCV忽略 */
&&&&&&&&&&&&&&& /*&像素的位深度,主要有以下支持格式: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,IPL_DEPTH_16S, IPL_DEPTH_32S,
IPL_DEPTH_32F&和IPL_DEPTH_64F */
&&&&&&& char colorModel[4]; /*&被OpenCV忽略 */
&&&&&&& char channelSeq[4]; /*&同上 */
&&&&&&& int dataO&&&& /* 0 -&交叉存取颜色通道, 1 - 分开的颜色通道.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&只有cvCreateImage可以创建交叉存取图像 */
&&&&&&&&&&&&&& /*图像原点位置: 0表示顶-左结构,1表示底-左结构 */
&&&&&&&&&&&&&&& /*&图像行排列方式 (4 or 8),在 OpenCV 被忽略,使用 widthStep 代替 */
&&&&&&&&&&&&&& /*&图像宽像素数 */
&&&&&&&&&&&&&& /*&图像高像素数*/
&&&&&&& struct _IplROI * /*&图像感兴趣区域,当该值非空时,
只对该区域进行处理 */
&&&&&&& struct _IplImage *maskROI; /*&在 OpenCV中必须为NULL */
&&&&&&& void *imageId;&&&& /*&同上*/
&&&&&&& struct _IplTileInfo *tileI /*同上*/
&&&&&&& int imageS&&&& /*&图像数据大小(在交叉存取格式下ImageSize=image-&height*image-&widthStep),单位字节*/
&&&&&&& char *imageD&&& /*&指向排列的图像数据 */
&&&&&&& int widthS&&&& /*&排列的图像行大小,以字节为单位 */
&&&&&&& int BorderMode[4]; /*&边际结束模式, 在 OpenCV 被忽略*/
&&&&&&& int BorderConst[4]; /*&同上 */
&&&&&&& char *imageDataO /*&指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
&&& } IplI
IplImage结构体是整个OpenCV函数库的基础,在定义该结构变量时需要用到函数cvCreatImage,变量定义方法如下:
IplImage* src=&/cvCreateImage&(cvSize(400,300), IPL_DEPTH_8U,3);
上句定义了一个IplImage指针变量src,图像的大小是400×300,图像颜色深度8位,3通道图像。
常用的五个函数(I/O)
1.&&&&&图像载入函数
函数cvLoadImage载入指定图像文件,并返回指向该文件的IplImage指针。函数支持bmp、jpg、 png、 tiff等格式的图像。其函数原型如下:
IplImage* cvLoadImage( const char* filename, int iscolor);
其中,filename 是待载入图像的名称,包括图像的扩展名;iscolor是一个辅助参数项,可选正数、零和负数三种值,正数表示作为三通道图像载入,零表示该图像作为单通道图像,负数表示载入图像的通道数由图像文件自身决定。
2.&&&&&窗口定义函数
函数cvNamedWindow定义一个窗口,用于显示图像。其函数原型如下:
int cvNamedWindow( const char* name, unsigned long flags );
其中,name是窗口名,flags是窗口属性指标值,可以选择CV_WINDOW_AUTOSIZE和0两种值。CV_WINDOW_AUTOSIZE表示窗口尺寸与图像原始尺寸相同,0表示以固定的窗口尺寸显示图像。
3.&&&&&图像显示函数
函数cvShowImage是在指定的窗口中显示图像,其函数原型如下:
void cvShowImage( const char* name, const CvArr* image );
其中,name是窗口名称,image是图像类型指针,一般是IplImage指针。
4.&&&&&图像保存函数
函数cvSaveImage以指定的文件名保存IplImage类型的指针变量,其函数原型如下:
int cvSaveImage( const char* filename, const CvArr* image );
其中,filename是图像保存路径和名称,image是IplImage指针变量。
5.&&&&&图像销毁函数
函数cvReleaseImage销毁已定义的IplImage指针变量,释放占用内存空间。其函数原型如下:
void cvReleaseImage( IplImage** image );
&其中,image为已定义的IplImage指针。&
&&IplImage类型除了继承了CvMat类的成员变量外,还定义了一些跟图像有关的成员变量。这个结构体最初是定义在Intel's Image Processing Library(IPL)中的。以下是该数据结构的定义:
typedef struct _IplImage {
& int&&&&&&&&&&&&&&&&& nS
& int&&&&&&&&&&&&&&&&& ID;
& int&&&&&&&&&&&&&&&&& nC
& int&&&&&&&&&&&&&&&&& alphaC
& int&&&&&&&&&&&&&&&&&
& char&&&&&&&&&&&&&&&& colorModel[4];
& char&&&&&&&&&&&&&&&& channelSeq[4];
& int&&&&&&&&&&&&&&&&& dataO
& int&&&&&&&&&&&&&&&&&
& int&&&&&&&&&&&&&&&&&
& int&&&&&&&&&&&&&&&&&
& int&&&&&&&&&&&&&&&&&
& struct _IplROI*&&&&&
& struct _IplImage*&&& maskROI;
& void*&&&&&&&&&&&&&&& imageId;
& struct _IplTileInfo* tileI
& int&&&&&&&&&&&&&&&&& imageS
& char*&&&&&&&&&&&&&&& imageD
& int&&&&&&&&&&&&&&&&& widthS
& int&&&&&&&&&&&&&&&&& BorderMode[4];
& int&&&&&&&&&&&&&&&&& BorderConst[4];
& char*&&&&&&&&&&&&&&& imageDataO
depth和nChannels是非常重要的属性。depth代表颜色深度,使用的是以下定义的宏,nChannels是通道数,为1,2,3或4。
depth的宏定义:
IPL_DEPTH_8U,无符号8bit整数(8u)
IPL_DEPTH_8S,有符号8bit整数(8s)
IPL_DEPTH_16S,有符号16bit整数(16s)
IPL_DEPTH_32S,有符号32bit整数(32s)
IPL_DEPTH_32F,32bit浮点数,单精度(32f)
IPL_DEPTH_64F,64bit浮点数,双精度(64f)
另外两个重要的成员变量是origin和dataOrder.
origin 变量可以有两个取值:IPL_ORIGIN_TL或者IPL_ORIGIN_BL,分别代表图像坐标系原点在左上角或是左下角。相应的,在计算机视觉领 域,一个重要的错误来源就是原点位置的定义不统一。例如,图像的来源不同,操作系统不同,视频解码codec不同,存储方式不同等等,都可以造成原点位置 的变化。例如,你可能认为你正在从图像上面的脸部附近取样,但实际上你却在图像下方的裙子附近取样。最初时,就应该检查一下你的系统中图像的原点位置,这 可以通过在图像上方画个形状等方式实现。
dataOrder的取值可以是IPL_DATA_ORDER_PIXEL或者 IPL_DATA_ORDER_PLANE,这个成员变量定义了多通道图像数据存储时颜色数据的排列方式,如果是 IPL_DATA_ORDER_PIXEL,通道颜色数据排列将会是BGRBGR...的交错排列,如果是IPL_DATA_ORDER_PLANE,则 每个通道的颜色值在一起,有几个通道,就有几个“颜色平面”。大多数情况下,通道颜色数据的排列是交错的。
widthStep与CvMat中的step类似,是以字节数计算的图像的宽度。成员变量imageData则保存了指向图像数据区首地址的指针。
最 后还有一个重要参数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的值。
访问图像中的数据
就象访问矩阵中元素一样,我们希望 用最直接的办法访问图像中的数据,例如,如果我们有一个三通道HSV图像(HSV色彩属性模式是根据色彩的三个基本属性:色相H、饱和度S和明度V来确定 颜色的一种方法),我们要将每个点的饱和度和明度设置成255,则我们可以使用指针来遍历图像,请对比一下,与矩阵的遍历有何不同:
void saturate_sv( IplImage* img ) {
& for( int y=0; y++ ) {
&&& uchar* ptr = (uchar*) (
&&&&& img-&imageData + y * img-&widthStep&
&&& for( int x=0; x++ ) {
&&&&& ptr[3*x+1] = 255;
&&&&& ptr[3*x+2] = 255;
注 意一下,3*x+1,3*x+2的方法,因为每一个点都有三个通道,所以这样设置。另外imageData成员的类型是uchar*,即字节指针类型,所 以与CvMat的data指针类型(union)不同,而不需要象CvMat那样麻烦(还记得step/4,step/8的那种情形吗)。
对roi和widthStep的补充
roi 和widthStep在实际工作中有很重要的作用,在很多情况下,使用它们会提高计算机视觉代码的执行速度。这是因为它们允许对图像的某一小部分进行操 作,而不是对整个图像进行运算。在OpenCV中,所有的对图像操作的函数都支持roi,如果你想打开roi,可以使用函数 cvSetImageROI(),并给函数传递一个矩形子窗口。而cvResetImageROI()是用于关闭roi的。
void cvSetImageROI(IplImage* image,CvRect rect);
void cvResetImageROI(IplImage* image);
注意,在程序中,一旦使用了roi做完相应的运算,就一定要用cvResetImageROI()来关闭roi,否则,其他操作执行时还会使用roi的定义。
#pragma comment( lib, &cxcore.lib& )
#pragma comment( lib, &cv.lib& )
#pragma comment( lib, &highgui.lib& )
int main(int argc, char** argv)
&&& IplImage*
&&& cvNamedWindow(&Example3_12_pre&, CV_WINDOW_AUTOSIZE);
&&& cvNamedWindow(&Example3_12_post&, CV_WINDOW_AUTOSIZE); &
&& &src = cvLoadImage(&dog.jpg&);
&& &int x = 150;
&& &int y = 300;
&& &int width = 200;
&& &int height = 200;
&& &int add = 150;
&& &cvShowImage( &Example3_12_pre&, src);
&& &cvSetImageROI(src, cvRect(x,y,width,height));
&& &cvAddS(src, cvScalar(add),src);//对roi区域的每通道颜色都加上一个值
&& &cvResetImageROI(src);
&& &cvShowImage( &Example3_12_post&,src);
&&& cvWaitKey();
&& cvReleaseImage( &src );
& cvDestroyWindow(&Example3_12_pre&);
& cvDestroyWindow(&Example3_12_post&);& &
&&& return 0;
操作结果见下图:
在上面的程序中,如果你在使用完roi后,没有使用 cvResetImageROI来关闭,效果是这样的:
我 们可以通过聪明地使用widthStep达到使用roi的同样的效果,这就需要创建一个子窗口,并让子窗口的图像数据指针指向主窗口中相应位置,而所做的 操作是针对子窗口而做的。创建子窗口的其他方面不用多说,但是要注意,子窗口的颜色深度,通道数,widthStep都与主窗口相同,可以看下面的画图示 意。
#pragma comment( lib, &cxcore.lib& )
#pragma comment( lib, &cv.lib& )
#pragma comment( lib, &highgui.lib& )
int main(int argc, char** argv)
&&& IplImage *src,*sub_
&&& cvNamedWindow(&Example3_13_pre&, CV_WINDOW_AUTOSIZE);
&&& cvNamedWindow(&Example3_13_post&, CV_WINDOW_AUTOSIZE); &
&& &src = cvLoadImage(&dog.jpg&);
&& &int x = 150;
&& &int y = 300;
&& &int width = 200;
&& &int height = 200;
&& &int add = 150;
&& &//子窗口的初始化
&& &sub_img =& cvCreateImageHeader(cvSize(width, height),src-&depth,src-&nChannels);
&&& sub_img-&origin = src-&&&& &
&& &//子窗口的widthStep和主窗口的widthStep相等
&&& sub_img-&widthStep = src-&widthS
&& &//注意这个公式,子窗口的图像数据指针首地址指向了主窗口中由子窗口左上角坐标x,y指定的相应位置
&&& sub_img-&imageData = src-&imageData + y * src-&widthStep& + x * src-&nC
&& &cvShowImage( &Example3_13_pre&, src);&& &
&& &cvAddS(sub_img, cvScalar(add),sub_img);
&& &cvShowImage( &Example3_13_post&,src);
&&& cvWaitKey();
&&& cvReleaseImage( &src );
&& &//释放子窗口的头部资源
&& &cvReleaseImageHeader(&sub_img);
&&& cvDestroyWindow(&Example3_13_pre&);
&&& cvDestroyWindow(&Example3_13_post&);& &
&&& return 0;
那么,既然我们有了很方便的roi机制,但为什么要费这么大劲用创建子窗口的办法呢?这是因为,roi机制一次只能作用于图像的一个子区域,如果要同时处理图像的多个子区域,还是用创建子窗口的办法最好,否则你就要频繁连续地对子区域进行设置roi和取消roi的操作了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:23902次
排名:千里之外
转载:23篇
(6)(1)(1)(3)(11)(1)(3)(1)}

我要回帖

更多关于 uiimage 旋转 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信