opencv学习笔记——C++读入bmp图像数据后,转为mat型矩阵,并显示输出

本文介绍了OpenCV中Mat类的基本用法,包括如何存储灰度图像和彩色图像,以及如何将图像数据从数组转换到Mat类,并实现图像的显示输出。

在开始之前,我们先介绍一下mat类的用法:

1、mat类存储图像

Mat类是OpenCV里使用广泛的一个类,其中最重要的一个作用就是作为存储图像的数据结构。那么Mat类如何存储的图像呢?

       我们都知道图像分为彩色图像和灰度图像,这里我有一个误区,一直认为彩色图像是一种三维矩阵,就是立方体的那种结构,一个图像分为三层。但是这种理解是错误的,其实在存储的图像不管是彩色的还是灰度图像,都是二维的矩阵,具体的存储格式如下:
(1)灰度图像的格式:

(2)彩色图像的格式:


虽然彩色图像由BGR三个通道,但是是存储在同一个平面内的,只不过OpenCV在这里把三列才当作一列,因此有img.cols等于图像的列数。

一般我们用Opencv读取的灰度图像的数据类型为uchar类型的,而彩色图像的一个像素的数据类型为<Vec3b>类型的,灰度图一个像素占用1个字节,而彩色图像一个像素3个字节。

2、将数组转化为mat类,并显示输出

这个程序承接上一个C++读图程序,在上一个程序中,已经实现了将bmp图像数据读取出来并存入矩阵,在这里要实现的就是把三通道的图像数据存入mat矩阵中,显示输出。代码如下:

rgb2opencvshow.cpp

  1. #include<cstdlib>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<iomanip>
  5. #include <opencv2/opencv.hpp>
  6. #include "opencv2/highgui/highgui.hpp"
  7. #include "opencv2/core/core.hpp"
  8. #include"readbmp.h"
  9. #include"savebmp.h"
  10. using namespace std;
  11. using namespace cv;
  12. unsigned int **out_r;
  13. unsigned int **out_g;
  14. unsigned int **out_b;
  15. void doIt()
  16. {
  17. char readPath[] = "D:\\C++_file\\image_deal_C++\\read_BMP\\lunpan.bmp";
  18. readBmp(readPath);
  19. // 输出整体图像信息
  20. cout << "\nwidth=" << bmpWidth << "\nheight=" << bmpHeight << "\nbiBitCount=" << biBitCount << endl;
  21. // 图像的字节数
  22. int linebyte1 = (bmpWidth*biBitCount / 8 + 3) / 4 * 4;
  23. int n = 0, m = 0, count_xiang_su = 0;
  24. out_r = new unsigned int *[bmpHeight]; //开辟指针数组
  25. for (int i = 0; i<bmpHeight; i++)
  26. out_r[i] = new unsigned int[bmpWidth];
  27. out_g = new unsigned int *[bmpHeight]; //开辟指针数组
  28. for (int i = 0; i<bmpHeight; i++)
  29. out_g[i] = new unsigned int[bmpWidth];
  30. out_b = new unsigned int *[bmpHeight]; //开辟指针数组
  31. for (int i = 0; i<bmpHeight; i++)
  32. out_b[i] = new unsigned int[bmpWidth];
  33. //初始化原始像素的数组。
  34. if (biBitCount == 8)
  35. {
  36. for (int i = 0; i<bmpHeight / 2; i++)
  37. {
  38. for (int j = 0; j<bmpWidth / 2; i++)
  39. *(pBmpBuf + i*linebyte1 + j) = 0;
  40. }
  41. }
  42. if (biBitCount == 24)
  43. {
  44. for (int i = 0; i<bmpHeight; i++)
  45. {
  46. for (int j = 0; j<bmpWidth; j++)
  47. {
  48. for (int k = 0; k<3; k++)//每像素RGB三个分量分别置0才变成黑色
  49. {
  50. m = *(pBmpBuf + i*linebyte1 + j * 3 + k);
  51. count_xiang_su++;
  52. }
  53. n++;
  54. }
  55. }
  56. cout << "总的像素个素为:" << n << endl;
  57. cout << "----------------------------------------------------" << endl;
  58. }
  59. if (biBitCount == 24)
  60. {
  61. for (int i = 0; i<bmpHeight; i++)
  62. {
  63. for (int j = 0; j<bmpWidth; j++)
  64. {
  65. out_r[bmpHeight - 1 - i][j] = pBmpBuf[j * 3 + 2 + bmpWidth*i * 3];
  66. out_g[bmpHeight - 1 - i][j] = pBmpBuf[j * 3 + 1 + bmpWidth *i * 3];
  67. out_b[bmpHeight - 1 - i][j] = pBmpBuf[j * 3 + bmpWidth *i * 3];
  68. }
  69. }
  70. Mat img_data(bmpHeight, bmpWidth, CV_8UC3);
  71. for (int i = 0; i<bmpHeight; i++){
  72. for (int j = 0; j<bmpWidth; j++){
  73. img_data.at<Vec3b>(i, j)[0] = out_b[i][j];
  74. img_data.at<Vec3b>(i, j) [1]= out_g[i][j];
  75. img_data.at<Vec3b>(i, j) [2]= out_r[i][j];
  76. }
  77. }
  78. namedWindow("lunpan");
  79. imshow("lunpan",img_data);
  80. waitKey(0);
  81. imwrite("D:\\C++_file\\image_deal_C++\\11.bmp",img_data);
  82. }
  83. //清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
  84. delete[]pBmpBuf;
  85. if (biBitCount == 8)
  86. delete[]pColorTable;
  87. }
  88. int main()
  89. {
  90. doIt();
  91. system("pause");
  92. return 0;
  93. }
测试该程序可知,输出结果与原图相同,成功实现数据的转换。









评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值