轉載:(213條消息) opencv學習筆記——C++讀入bmp圖像數據后,轉為mat型矩陣,並顯示輸出_wanty_chen的博客-CSDN博客_opencv讀取bmp圖片
在開始之前,我們先介紹一下mat類的用法:
1、mat類存儲圖像
Mat類是OpenCV里使用廣泛的一個類,其中最重要的一個作用就是作為存儲圖像的數據結構。那么Mat類如何存儲的圖像呢?
我們都知道圖像分為彩色圖像和灰度圖像,這里我有一個誤區,一直認為彩色圖像是一種三維矩陣,就是立方體的那種結構,一個圖像分為三層。但是這種理解是錯誤的,其實在存儲的圖像不管是彩色的還是灰度圖像,都是二維的矩陣,具體的存儲格式如下:
(1)灰度圖像的格式:
(2)彩色圖像的格式:
雖然彩色圖像由BGR三個通道,但是是存儲在同一個平面內的,只不過OpenCV在這里把三列才當作一列,因此有img.cols等於圖像的列數。
一般我們用Opencv讀取的灰度圖像的數據類型為uchar類型的,而彩色圖像的一個像素的數據類型為<Vec3b>類型的,灰度圖一個像素占用1個字節,而彩色圖像一個像素3個字節。
2、將數組轉化為mat類,並顯示輸出
這個程序承接上一個C++讀圖程序,在上一個程序中,已經實現了將bmp圖像數據讀取出來並存入矩陣,在這里要實現的就是把三通道的圖像數據存入mat矩陣中,顯示輸出。代碼如下:
rgb2opencvshow.cpp
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include"readbmp.h"
#include"savebmp.h"
using namespace std;
using namespace cv;
unsigned int **out_r;
unsigned int **out_g;
unsigned int **out_b;
void doIt()
{
char readPath[] = "D:\\C++_file\\image_deal_C++\\read_BMP\\lunpan.bmp";
readBmp(readPath);
// 輸出整體圖像信息
cout << "\nwidth=" << bmpWidth << "\nheight=" << bmpHeight << "\nbiBitCount=" << biBitCount << endl;
// 圖像的字節數
int linebyte1 = (bmpWidth*biBitCount / 8 + 3) / 4 * 4;
int n = 0, m = 0, count_xiang_su = 0;
out_r = new unsigned int *[bmpHeight]; //開辟指針數組
for (int i = 0; i<bmpHeight; i++)
out_r[i] = new unsigned int[bmpWidth];
out_g = new unsigned int *[bmpHeight]; //開辟指針數組
for (int i = 0; i<bmpHeight; i++)
out_g[i] = new unsigned int[bmpWidth];
out_b = new unsigned int *[bmpHeight]; //開辟指針數組
for (int i = 0; i<bmpHeight; i++)
out_b[i] = new unsigned int[bmpWidth];
//初始化原始像素的數組。
if (biBitCount == 8)
{
for (int i = 0; i<bmpHeight / 2; i++)
{
for (int j = 0; j<bmpWidth / 2; i++)
*(pBmpBuf + i*linebyte1 + j) = 0;
}
}
if (biBitCount == 24)
{
for (int i = 0; i<bmpHeight; i++)
{
for (int j = 0; j<bmpWidth; j++)
{
for (int k = 0; k<3; k++)//每像素RGB三個分量分別置0才變成黑色
{
m = *(pBmpBuf + i*linebyte1 + j * 3 + k);
count_xiang_su++;
}
n++;
}
}
cout << "總的像素個素為:" << n << endl;
cout << "----------------------------------------------------" << endl;
}
if (biBitCount == 24)
{
for (int i = 0; i<bmpHeight; i++)
{
for (int j = 0; j<bmpWidth; j++)
{
out_r[bmpHeight - 1 - i][j] = pBmpBuf[j * 3 + 2 + bmpWidth*i * 3];
out_g[bmpHeight - 1 - i][j] = pBmpBuf[j * 3 + 1 + bmpWidth *i * 3];
out_b[bmpHeight - 1 - i][j] = pBmpBuf[j * 3 + bmpWidth *i * 3];
}
}
Mat img_data(bmpHeight, bmpWidth, CV_8UC3);
for (int i = 0; i<bmpHeight; i++){
for (int j = 0; j<bmpWidth; j++){
img_data.at<Vec3b>(i, j)[0] = out_b[i][j];
img_data.at<Vec3b>(i, j) [1]= out_g[i][j];
img_data.at<Vec3b>(i, j) [2]= out_r[i][j];
}
}
namedWindow("lunpan");
imshow("lunpan",img_data);
waitKey(0);
imwrite("D:\\C++_file\\image_deal_C++\\11.bmp",img_data);
}
//清除緩沖區,pBmpBuf和pColorTable是全局變量,在文件讀入時申請的空間
delete[]pBmpBuf;
if (biBitCount == 8)
delete[]pColorTable;
}
int main()
{
doIt();
system("pause");
return 0;
}
測試該程序可知,輸出結果與原圖相同,成功實現數據的轉換。
————————————————
版權聲明:本文為CSDN博主「wanty_chen」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wanty_chen/article/details/80023871
