opencv笔记(一)——读取、显示、另存为、批量读取照片

一、批量有序读取图片

#include<opencv2/opencv.hpp>

using namespace cv;

void main()
{
    //批量读取图片(有序)
    char filename[50];
    char winName[50];
    Mat srcImg;
    for (int i = 1; i < 100; i++)
    {
        sprintf(filename,"%d.bmp",i);
        sprintf(winName,"NO--%d",i);
        srcImg=imread(filename);
        if (srcImg.empty())
            break;
        imshow(winName,srcImg);
    }
    waitKey(0);
    destroyAllWindows();
}

二、读、写、存图片

OpenCV中最基本的操作:读取、显示、保存图片。

OpenCV2.0版本引入与Matlab命令相同的函数,imread、imshow、imwrite,获取图片更将方便。

2.1 读取文件 imread

1

Mat imread(const string& filename, int flags=1 )

Mat是在矩阵中存储图片的数据结构,它声明在 “opencv2/core/core.hpp”头文件中。
imread()是声明在 “opencv2/highgui/highgui.hpp”的函数,它从文件加载一个图片并存储在Mat数据结构中

它的参数:

    • filename —— 图片的来源、名字或者文件的位置。如果只提供文件名,那么文件应该和C++文件在同一目录,否则必须提供图片的全路径。
    • flags ——表示载入后图片的颜色模式。有5个可能的输入。
      • CV_LOAD_IMAGE_UNCHANGED –以RGB模式载入图片。在每个通道中,每个像素的位深为8 bit,通道数(颜色)保持不变。
      • CV_LOAD_IMAGE_GRAYSCALE – 位深=8 bit 通道数=1(颜色变灰)
      • CV_LOAD_IMAGE_COLOR -位深=?, 通道数=3
      • CV_LOAD_IMAGE_ANYDEPTH – 位深不变 ,通道数=?
      • CV_LOAD_IMAGE_ANYCOLOR – 位深=?, 通道数不变

      上面的值还可以组合使用,比如:
      CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR – 位深不变,通道数比便
      CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYDEPTH – 位深不变,通道数=3

如果你不确定使用哪个,就是用CV_LOAD_IMAGE_COLOR 。

 

显示图片需要一个窗口。

2.2 创建窗口 namedWindow

1

void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE )

CV_WINDOW_AUTOSIZE 窗口大小自动调整到显示图片的大小
CV_WINDOW_NORMAL 只在Qt中使用,可以改变窗口大小

2.3 显示图片 imshow

1

void imshow(const string& winname, InputArray mat)

在窗口中显示图片,对于NORMAL的窗口,把图片缩放到窗口固定大小,再显示。根据图像数据的深度,对图像进行下面的处理:

8-bit unsigned 直接显示
16-bit unsigned or 32-bit integer 像素点值除以256,即把[0,255*256] 映射到 [0,255]
32-bit floating-point 像素点值乘以255,即把[0,1] 映射到 [0,255]

所以,imshow可以正常显示取值范围[0,255]的uchar型图像、取值范围[0,1]的float或double类型图像,中间一种数据格式没用过。

显示图像后,为了避免程序向下运行以致窗口一闪而过,需要等待一旦时间,waitKey正是这个功能。

2.4 等待键盘按键 waitKey

1  

int waitKey(int delay=0)

delay小于等于0时,一直等待,只到用户按键,再继续执行。
delay大于0时,在delay微秒内等待用户按键。

处理过的图像需要保存到文件中。

2.5 保存图像 imwrite

1

bool imwrite(const string& filename, InputArray img, const vector& params=vector() )

该函数是把程序中的Mat类型的矩阵保存为图像到指定位置。

   (1)参数filename为所需保存图像的文件目录和文件名。这里的文件名需要带有图像格式后缀的,目前OpenCV该函数只支持JPEG,PNG,PPM,PGM,PBM,TIFF等。并不是所有Mat类型都支持。

     (2)img参数为图像数据来源,其类型为Mat

      注意也不是所有格式的Mat型数据都能被使用保存为图片,目前OpenCV主要只支持单通道和3通道的图像,并且此时要求其深度为8bit和16bit无符号(即CV_16U)。所以其他一些数据类型是不支持的,比如说float型等。如果Mat类型数据的深度和通道数不满足上面的要求,则需要使用convertTo()函数和cvtColor()函数来进行转换。convertTo()函数负责转换数据类型不同的Mat,即可以将类似float型的Mat转换到imwrite()函数能够接受的类型。而cvtColor()函数是负责转换不同通道的Mat,因为该函数的第4个参数就可以设置目的Mat数据的通道数(只是我们一般没有用到它,一般情况下这个函数是用来进行色彩空间转换的)。另外也可以不用imwrite()函数来存图片数据,可以直接用通用的XML IO接口函数将数据存在XML或者YXML中。

      (3)参数params是用来设置对应图片格式的参数的,因为一般情况下这些图片格式都是经过了压缩的,这里就是设置这些压缩参数来控制图片的质量。该参数是一个vector<int>类型,里面分别存入paramId_1, paramValue_1, paramId_2, paramValue_2, ... 也就是说存入一对属性值。如果不设置该参数的话,则程序会自动根据所保存的图像格式采用一个默认的参数。当前支持如下参数:

  • JPEG:压缩质量 ( CV_IMWRITE_JPEG_QUALITY ),从0到100(数值越高质量越好),默认值为95。
  • PNG:compression level ( CV_IMWRITE_PNG_COMPRESSION ) 从0到9。 数值越高,文件大小越小,压缩时间越长。默认值为3。
  • PPM, PGM, or PBM:二进制标志 ( CV_IMWRITE_PXM_BINARY ),0 或 1。默认值为1。

还有一组函数,用于从内存读取数据和向内存写入数据。

2.6 从内存读图片 imdecode

1

Mat imdecode(InputArray buf, int flags)

2.7 写图片到内存 imencode

1

bool imencode(const string& ext, InputArray img, vector& buf, const vector& params=vector())

ext – 图片的扩展名
img – 要保存的图片
buf – 输出缓存,改变大小以适应数据
params – 格式相关的参数,参见imwrite。

上面两个函数的示例代码如下所示,来自http://code.google.com/p/opencvjp-sample/source/browse/trunk/cpp/encode_decode_test.cpp?r=63 。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

 

#include <iostream>

#include <fstream>

#include <cv.h>

#include <highgui.h>

using namespace std;

using namespace cv;

 

double getPSNR(Mat& src1, Mat& src2, int bb=0);

 

int main(int argc, char** argv)

{

        Mat src = imread("lenna.png");

 

        //(1) jpeg compression

        vector<uchar> buff;//buffer for coding

        vector<int> param = vector<int>(2);

        param[0]=CV_IMWRITE_JPEG_QUALITY;

        param[1]=95;//default(95) 0-100

 

        imencode(".jpg",src,buff,param);

        cout<<"coded file size(jpg)"<<buff.size()<<endl;//fit buff size automatically.

        Mat jpegimage = imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR);

 

        //(2) png compression

        param[0]=CV_IMWRITE_PNG_COMPRESSION;

        param[1]=3;//default(3)  0-9.

        imencode(".png",src,buff,param);

        cout<<"coded file size(png)"<<buff.size()<<endl;

        Mat pngimage = imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR);

 

        //(3) intaractive jpeg compression

        char name[64];

        namedWindow("jpg");

        int q=95;

        createTrackbar("quality","jpg",&q,100);

        int key = 0;

        while(key!='q')

        {

                param[0]=CV_IMWRITE_JPEG_QUALITY;

                param[1]=q;

                imencode(".jpg",src,buff,param);

                Mat show = imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR);

 

                double psnr = getPSNR(src,show);//get PSNR

                double bpp = 8.0*buff.size()/(show.size().area());//bit/pixe;

                sprintf(name,"quality:%03d, %.1fdB, %.2fbpp",q,psnr,bpp);

                putText(show,name,Point(15,50), FONT_HERSHEY_SIMPLEX,1,CV_RGB(255,255,255),2);

                imshow("jpg",show);

                key = waitKey(33);

 

                if(key =='s')

                {

                        //(4) data writing

                        sprintf(name,"q%03d_%.2fbpp.png",q,bpp);

                        imwrite(name,show);

 

                        sprintf(name,"q%03d_%.2fbpp.jpg",q,bpp);

                        param[0]=CV_IMWRITE_JPEG_QUALITY;

                        param[1]=q;

                        imwrite(name,src,param);;

                }

        }

}

double getPSNR(Mat& src1, Mat& src2, int bb)

{

        int i,j;

        double sse,mse,psnr;

        sse = 0.0;

 

        Mat s1,s2;

        cvtColor(src1,s1,CV_BGR2GRAY);

        cvtColor(src2,s2,CV_BGR2GRAY);

 

        int count=0;

        for(j=bb;j<s1.rows-bb;j++)

        {

                uchar* d=s1.ptr(j);

                uchar* s=s2.ptr(j);

 

                for(i=bb;i<s1.cols-bb;i++)

                {

                        sse += ((d[i] - s[i])*(d[i] - s[i]));

                        count++;

                }

        }

        if(sse == 0.0 || count==0)

        {

                return 0;

        }

        else

        {

                mse =sse /(double)(count);

                psnr = 10.0*log10((255*255)/mse);

                return psnr;

        }

}

 

最后,应该释放窗口。窗口可以自动释放,也可以手动关闭。

释放窗口 destroyWindow  destroyAllWindow

1

2

3

4

 

void destroyWindow(const string& winname)

void destroyAllWindows()

 

第一个释放单个窗口,第二个释放所有窗口。

 

转自:http://windrocblog.sinaapp.com/?p=465

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值