Opencv--Iplimage中像素操作
2016-02-24 14:20
225 查看
首先,我们要知道几个opencv常用的数据类型:IPlImage。Mat,cvMat。
笔者在一个项目中,花了大量的时间用IplImage类型载入图片,然后转成Mat类型操作,再转成IPlImage类型进行显示,这样做当然是因为Mat矩阵能够轻松的操作,但是也给程序带来冗杂的代码。如下:
这样是要建立一个中间变量。所有的形式可以参考IPlImage与Mat,cvMat之间的转换方法代码。
三者的关系之前已经讨论过:http://blog.csdn.net/samkieth/article/details/49475065
那么,我们看看如何对IPlImage直接进行像素操作:
1如果变成灰度图,就是单通道图像,获取的就是每一个像素点的灰度值
2如果是三通道图像,获取的就是每一个像素点的BGR值,然后分别获取B值,G值和R值
配置好OpenCV以后,包含以下两个头文件:
#include "cv.h"
#include "highgui.h"
IplImage* image=cvLoadImage("D:\\123.jpg",-1);
//函数cvLoadImage()的第1个参数是图像文件的路径.
//第2个参数是读取图像的方式:-1表示按照图像本身的类型来读取,1表示强制彩色化,0表示
//强制灰值化.
if(image==NULL)
{
MessageBox("无法读取图像数据!", "提示",MB_OK);
//在MFC工程中这样用
//若在win32控制台程序中,用printf("无法读取图像数据!\n");
return;
//不作任何操作,就不会执行后面的程序了
}
cvNamedWindow("图像显示",CV_WINDOW_AUTOSIZE);
//该函数的功能是按照指定方式创建一个窗口,用于显示图像.
//第1个参数是窗口的名称,自己可以任意设置
//第2个参数表示窗口的大小会自动根据图像尺寸而变化
cvShowImage("图像显示",image);
//该函数的功能是在指定的窗口上显示图像.
//第1个参数是显示图像窗口的名称
//第2个参数是要显示的图像
cvSaveImage("D:\\saveImage.jpg",image);
//该函数的功能是将图像另存为
//第1个参数是保存的路径,自己可以设置其它路径
//第2个参数是要保存的图像
cvWaitKey(0);
//一直等待按键 没有这句的话 图像不能正常显示
cvReleaseImage(&image);
//释放图像内存
cvDestroyWindow("图像显示");
//销毁窗口资源 //,
split函数的主要功能是把一个彩色图像分割成3个通道,方便进一步的图像处理,具体说明如下:
split Divides a multi-channel array into several single-channel arrays.
C++: void split(const Mat& mtx, Mat* mv)
C++: void split(const Mat& mtx, vector& mv)
其实还有一个函数merge可以实现相反的操作,简单说明如下:
merge Composes a multi-channel array from several single-channel arrays.
C++: void merge(const Mat* mv, size_t count, OutputArray dst)
C++: void merge(const vector& mv, OutputArray dst)
其示例代码如下:
笔者在一个项目中,花了大量的时间用IplImage类型载入图片,然后转成Mat类型操作,再转成IPlImage类型进行显示,这样做当然是因为Mat矩阵能够轻松的操作,但是也给程序带来冗杂的代码。如下:
<span style="font-size:18px;">IplImage* outputpFrame = NULL;//转IplImage用 IplImage* outputpFr = NULL; IplImage* outputpBk = NULL;</span>
这样是要建立一个中间变量。所有的形式可以参考IPlImage与Mat,cvMat之间的转换方法代码。
三者的关系之前已经讨论过:http://blog.csdn.net/samkieth/article/details/49475065
那么,我们看看如何对IPlImage直接进行像素操作:
1如果变成灰度图,就是单通道图像,获取的就是每一个像素点的灰度值
IplImage* img = cvLoadImage("yu.jpg", 0); for (int i = 0; i < img->height; i++) { for (int j = 0; j < img->width; j++) { //方法一:使用cvGet2D()函数间接访问 CvScalar s = cvGet2D(img, i, j);//其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。 cout<<"gray value="<<s.val[0]<<endl; //方法二:使用直接访问 uchar val = ((uchar *)(img->imageData + i*img->widthStep))[j];//i和j的意义同上 cout<<"gray value="<<val); } }
2如果是三通道图像,获取的就是每一个像素点的BGR值,然后分别获取B值,G值和R值
IplImage* img = cvLoadImage("test.bmp", 1); for (int i = 0; i < img->height; i++) { for (int j = 0; j < img->width; j++) { //方法一:使用cvGet2D()函数间接访问 CvScalar s=cvGet2D(img,i,j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。 cout<<"B="<<s.val[0]<<"G="<<s.val[1]<<"R="<<s.val[2]<<endl;//注意是BGR顺序 //方法二:使用直接访问 int bVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]; // B int gVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]; // G int rVal = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]; // R cout<<"B="<<Bval<<"G="<<Gval<<"R="<<Rval<<endl;//注意是BGR顺序 } }
配置好OpenCV以后,包含以下两个头文件:
#include "cv.h"
#include "highgui.h"
IplImage* image=cvLoadImage("D:\\123.jpg",-1);
//函数cvLoadImage()的第1个参数是图像文件的路径.
//第2个参数是读取图像的方式:-1表示按照图像本身的类型来读取,1表示强制彩色化,0表示
//强制灰值化.
if(image==NULL)
{
MessageBox("无法读取图像数据!", "提示",MB_OK);
//在MFC工程中这样用
//若在win32控制台程序中,用printf("无法读取图像数据!\n");
return;
//不作任何操作,就不会执行后面的程序了
}
cvNamedWindow("图像显示",CV_WINDOW_AUTOSIZE);
//该函数的功能是按照指定方式创建一个窗口,用于显示图像.
//第1个参数是窗口的名称,自己可以任意设置
//第2个参数表示窗口的大小会自动根据图像尺寸而变化
cvShowImage("图像显示",image);
//该函数的功能是在指定的窗口上显示图像.
//第1个参数是显示图像窗口的名称
//第2个参数是要显示的图像
cvSaveImage("D:\\saveImage.jpg",image);
//该函数的功能是将图像另存为
//第1个参数是保存的路径,自己可以设置其它路径
//第2个参数是要保存的图像
cvWaitKey(0);
//一直等待按键 没有这句的话 图像不能正常显示
cvReleaseImage(&image);
//释放图像内存
cvDestroyWindow("图像显示");
//销毁窗口资源 //,
split函数的主要功能是把一个彩色图像分割成3个通道,方便进一步的图像处理,具体说明如下:
split Divides a multi-channel array into several single-channel arrays.
C++: void split(const Mat& mtx, Mat* mv)
C++: void split(const Mat& mtx, vector& mv)
其实还有一个函数merge可以实现相反的操作,简单说明如下:
merge Composes a multi-channel array from several single-channel arrays.
C++: void merge(const Mat* mv, size_t count, OutputArray dst)
C++: void merge(const vector& mv, OutputArray dst)
其示例代码如下:
#include "stdafx.h" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include #include using namespace cv; int main( int argc, char** argv ) { Mat src, srcOfMerge; vector mv; /// Read image ( same size, same type ) src = imread("d:\\images\\WindowsLogo.jpg"); if( !src.data ) { printf("Error loading src \n"); return -1; } split(src,mv); /// Create Windows namedWindow("RGB", 1); namedWindow("R", 1); namedWindow("R", 1); namedWindow("R", 1); namedWindow("srcOfMerge", 1); imshow( "RGB", src); imshow("R",mv[0]); imshow("G",mv[1]); imshow("B",mv[2]); merge(mv,srcOfMerge); imshow("srcOfMerge",srcOfMerge); waitKey(0); return 0; }
相关文章推荐
- 网站汇总
- Java 开发必会的 Linux 命令
- TOMCAT源码导入eclipse
- linux 下 apache启动、停止、重启命令
- 华为SD-DC²架构, 聚焦数据中心云化
- hadoop 集群常见错误解决办法
- Linux下gcc安装与使用(常用的gcc命令)
- Hadoop 三台主机 集群搭建 详解(测试)
- Eclipse导入Tomcat源码
- Hadoop开启、关闭调试信息方法
- 常用的Linux指令+Android下的Linux指令
- linux下tomcat开启远程调试
- nova flavor中的disk和ephemeral
- 查看linux服务器CPU详细情况
- linux 添加链接与删除链接(ln命令的用法)
- CentOS 6.5配置本地YUM源
- CentOS 6.5 安装 MySQL 5.6.17 并修改MySQL的root用户密码
- Tomcat7 部署CGI程序
- eoiioe linux下解压命令大全
- Linux内核分析 笔记一——by王玥