Opencv学习——图像及视频读取
2017-04-30 16:39
288 查看
Opencv的图像读取有C和C++接口的,由于C接口涉及到指针操作,需要对指针进行管理。而C++接口就比较简单了,本文也主要以C++接口来进行图像操作。Opencv2.0版本后新增了Mat操作,相比之前的版本简单了很多。读取一张图片的函数类似于matlab的方式。
在opencv中图像通道的顺序为BGR。图像像素操作一般有三种方法,考虑到效率的问题还是C风格的指针操作比较高效,函数isContinuous()将图像转化为单行形式,这样能够加速浏览过程。
Mat& ScanImageAndReduceC(Mat &I, const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols*channels;
if(I.isContinuous())
{
nCols *=nRows;
nRows = 1;
}
int i,j;
uchar* p;
for(i=0;i<nRow;i++)
{
p = I.ptr<uchar>(i);
for(j=0;j<nCols;j++)
{
p[j] = table[p[j]];
}
}
Return I;
}迭代方法是比较安全的方法:
Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
Const int channels = I.channels();
Switch(channels)
{
case 1: //单通道
{
MatIterator_<uchar> it, end;
for(it = I.begin<uchar>(),end = I.end<uchar>();it!=end;++it)
*it = table[*it];
break;
}
case 3: //3通道
{
MatIterator_<Vec3b> it, end;
for(it = I.begin<Vec3b>(),end = I.end<Vec3b>();it!=end;++it)
{
(*it)[0] = table[(*it)[0]];
(*it)[1] = table[(*it)[1]];
(*it)[2] = table[(*it)[2]];
}
break;
}
}
return I;
} 最后是不太推荐的图像扫描方式,只适合获取或更改图像中的随机像素,使用的是at()函数:
Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
Const int channels = I.channels();
Switch(channels)
{
case 1: //单通道
{
for(int i=0;i<I.rows;i++)
for(int j=0;j<I.cols;j++)
I.at<uchar>(i,j) = table[I.at<uchar>(i,j)];
break;
}
case 3: //3通道
{
Mat_<Vec3b> _I = I;
for(int i=0;i<I.rows;i++)
for(int j=0;j<I.cols;j++)
{
_I(i,j)[0] = table[I(i,j)[0]];
_I(i,j)[1] = table[I(i,j)[1]];
_I(i,j)[2] = table[I(i,j)[2]];
}
I = _I;
break;
}
}
return I;
}读取图片比较简单,从摄像机读取视频则稍微复杂一点://读取视频
//图像读取 #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat img = imread("lena.jpg",1); if(img.empty()) { cout<<"Cannot open the image!"<<endl; } namedWindow("lena",CV_WINDOW_AUTOSIZE); //可以不用此句 imshow("lena",img); waitKey(100); imwrite("lenaCopy.jpg",img); return 0; }
在opencv中图像通道的顺序为BGR。图像像素操作一般有三种方法,考虑到效率的问题还是C风格的指针操作比较高效,函数isContinuous()将图像转化为单行形式,这样能够加速浏览过程。
Mat& ScanImageAndReduceC(Mat &I, const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols*channels;
if(I.isContinuous())
{
nCols *=nRows;
nRows = 1;
}
int i,j;
uchar* p;
for(i=0;i<nRow;i++)
{
p = I.ptr<uchar>(i);
for(j=0;j<nCols;j++)
{
p[j] = table[p[j]];
}
}
Return I;
}迭代方法是比较安全的方法:
Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
Const int channels = I.channels();
Switch(channels)
{
case 1: //单通道
{
MatIterator_<uchar> it, end;
for(it = I.begin<uchar>(),end = I.end<uchar>();it!=end;++it)
*it = table[*it];
break;
}
case 3: //3通道
{
MatIterator_<Vec3b> it, end;
for(it = I.begin<Vec3b>(),end = I.end<Vec3b>();it!=end;++it)
{
(*it)[0] = table[(*it)[0]];
(*it)[1] = table[(*it)[1]];
(*it)[2] = table[(*it)[2]];
}
break;
}
}
return I;
} 最后是不太推荐的图像扫描方式,只适合获取或更改图像中的随机像素,使用的是at()函数:
Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table)
{
//accept only char type matrices
CV_ASSERT(I.depth()!=sizeof(uchar));
Const int channels = I.channels();
Switch(channels)
{
case 1: //单通道
{
for(int i=0;i<I.rows;i++)
for(int j=0;j<I.cols;j++)
I.at<uchar>(i,j) = table[I.at<uchar>(i,j)];
break;
}
case 3: //3通道
{
Mat_<Vec3b> _I = I;
for(int i=0;i<I.rows;i++)
for(int j=0;j<I.cols;j++)
{
_I(i,j)[0] = table[I(i,j)[0]];
_I(i,j)[1] = table[I(i,j)[1]];
_I(i,j)[2] = table[I(i,j)[2]];
}
I = _I;
break;
}
}
return I;
}读取图片比较简单,从摄像机读取视频则稍微复杂一点://读取视频
//读取视频 int main(int,char**) { VideoCapture cap(0); if(!cap.isOpened()) { cout<<"Cannot Open the camera!"<<endl; return -1; } double dwidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //获取图像尺寸 double dheight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); Mat frame; while(1) { bool bSuccess = cap.read(frame); if(!bSuccess) { cout<<"Cannot read a frame from video stream!"<<endl; break; } imshow("video",frame); if(waitKey(30)==27) { cout<<"ESC key is pressed by user"<<endl; break; } } return 0; }将VideoCapture cap(0)改为VideoCapture cap("camera.avi"),即可读取本地视频。以上是opencv读写图像及视频的简介。
相关文章推荐
- 学习OPENCV之读取图像和视频
- OpenCV学习——图像信息读取和倒置
- OpenCV学习笔记 利用MFC的Picture控件显示图像+播放视频和捕获摄像头画面 .
- OpenCV学习之视频读取与帧的提取、显示及保存
- OpenCV读取视频和图像序列
- OpenCV学习笔记(9)利用MFC的Picture控件显示图像+播放视频和捕获摄像头画面
- OpenCV学习笔记-读取视频文件
- opencv 学习第四天 学习opencv(中文版) 总结一下opencv的图像视频的简单应用
- Opencv学习_3 (Opencv读取视频 &视频进度控制 &写视频)
- OpenCV学习(二)读取视频文件和摄像头
- OpenCV 从视频或摄像头中读取图像示例
- 利用MFC和opencv读取视频显示图像方法
- opencv读取摄像头图像和读取视频文件图像
- OpenCV学习笔记(4)视频文件的读取与保存(2010-01-23 更新)
- 【OpenCV学习笔记5】读取图像中任意点的像素值
- 【OpenCV学习】图像信息读取和倒置
- OpenCV学习笔记之图像视频显示
- [学习opencv]图像读取写入,加减乘除
- Opencv学习笔记(2)模块,图像读取、显示、叠加、融合、颜色分离、亮度、对比度
- 读取视频文件存盘(学习openCV课后题2.3)