1. 程式人生 > 其它 >opencv學習筆記——C++讀入bmp影象資料後,轉為mat型矩陣,並顯示輸出

opencv學習筆記——C++讀入bmp影象資料後,轉為mat型矩陣,並顯示輸出

轉載:(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