目的
先說說理論:
在圖像處理中,用RGB三個分量(R:Red,G:Green,B:Blue),即紅、綠、藍三原色來表示真彩色,R分量,G分量,B分量的取值范圍均為0~255,比如電腦屏幕上的一個紅色的像素點的三個分量的值分別為:255,0,0。
那么什么叫圖片的灰度化呢?其實很簡單,就是讓像素點矩陣中的每一個像素點都滿足下面的關系:R=G=B(就是紅色變量的值,綠色變量的值,和藍色變量的值,這三個值相等,“=”的意思不是程序語言中的賦值,是數學中的相等),此時的這個值叫做灰度值。
這是理論,實際在Opencv中,灰度化就是單通道圖了,因為RGB都一樣了,沒必要都存儲了。
再說說具體目的:
目的就是判斷一個圖片是否灰化了。
網上,包括,AI上很多方法都不行。
分析
先把一張簡單的圖片進行灰化操作:
void productGrayImage()
{cv::Mat image(10, 10, CV_8UC3);// 遍歷圖像的每個像素for (int x = 0; x < image.rows; ++x) {for (int y = 0; y < image.cols; ++y) {// 獲取像素的指針cv::Vec3b& pixel = image.at<cv::Vec3b>(x, y);// 為BGR通道分別賦值pixel[0] = 255; // 藍色通道 (B)pixel[1] = 9; // 綠色通道 (G)pixel[2] = 10; // 紅色通道 (R)}}image.at<cv::Vec3b>(0, 0)[0] = 255;image.at<cv::Vec3b>(0, 0)[1] = 255;image.at<cv::Vec3b>(0, 0)[2] = 255;printf("image.type=%d\n", image.type());// 顯示圖像cv::imshow("Colored Image", image);cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);printf("image.type=%d\n", image.type());for (int x = 0; x < image.rows; ++x){for (int y = 0; y < image.cols; ++y){// 獲取像素的指針int pixel = image.at<uchar>(x, y);printf("%d ",pixel);}printf("\n");}
// cv::imwrite("gray.jpg", image);cv::imshow("gray Image", image);cv::imwrite("gray.bmp", image);
}
運行情況:
生成gray.bmp的情況:
下面判斷是否灰化:
void judgeGrayImageInfo(QString imagePath)
{//cv::Mat image = cv::imread(imagePath.toStdString(), cv::IMREAD_GRAYSCALE); // 加載圖像QImage image = QImage(imagePath);qDebug()<<"image.colorCount="<<image.colorCount();qDebug()<<"image.format="<<image.format();cv::Mat mat = cv::imread(imagePath.toStdString()); // 加載圖像qDebug()<<"mat.type="<<mat.type();for (int i = 0; i < mat.rows; i++){for (int j = 0; j < mat.cols; j++){if(mat.type() == 16){cv::Vec3b pixel = mat.at<cv::Vec3b>(i, j);printf("%d,%d,%d ", pixel[0], pixel[1], pixel[2]);}else{int pixel = mat.at<uchar>(i, j);printf("%d ", pixel);}}printf("\n");}if (isGrayImage(mat)) {std::cout << "The image is grayscale." << std::endl;} else {std::cout << "The image is not grayscale." << std::endl;}cv::imshow("gray Image", mat);cv::Mat mats[3];split(mat,mats);cv::imshow("gray gray Image", mat);mat = mats[0];int uniqueColors = cv::countNonZero(mat);qDebug()<<"uniqueColors="<<uniqueColors;qDebug()<<"mat.type="<<mat.type();if(mat.type() == 0){mat.at<uchar>(0, 1) = 255;mat.at<uchar>(0, 2) = 255;}for (int i = 0; i < mat.rows; i++){for (int j = 0; j < mat.cols; j++){if(mat.type() == 16){cv::Vec3b pixel = mat.at<cv::Vec3b>(i, j);printf("%d,%d,%d ", pixel[0], pixel[1], pixel[2]);}else{int pixel = mat.at<uchar>(i, j);printf("%d ", pixel);}}printf("\n");}
}
運行情況:
可以見得,能正確判斷是否灰化
總結
灰化是怎么判斷的呢?
灰化圖在opencv中是單通道圖,但保存時,會轉化成RGB模式的圖。
所以,再加載,通過通道數,判斷是否是灰度圖,這樣是不對的。
解決方法:
首先,一個圖片在保存時,其實是以RGB模式保存的,這也是操作系統默認的保存方式。
那一個灰化圖在保存時,會默認轉化為RGB模式,怎么轉化,其就是把一個灰化值重復為三份,分別對應RGB,這樣就可以了。
如圖所示:
知道這個情況了:
就知道如何判斷一個圖是否灰化了:
那就是:R=G=B就可以了。
具體代碼見:
https://download.csdn.net/download/maokexu123/88862864