Opencv学习——图像及视频读取

来源:互联网 发布:微念科技有限公司 知乎 编辑:程序博客网 时间:2024/05/22 15:04

Opencv的图像读取有CC++接口的,由于C接口涉及到指针操作,需要对指针进行管理。而C++接口就比较简单了,本文也主要以C++接口来进行图像操作。Opencv2.0版本后新增了Mat操作,相比之前的版本简单了很多。读取一张图片的函数类似于matlab的方式。

//图像读取#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读写图像及视频的简介。





0 0
原创粉丝点击