文章目錄
- 0、知識點
- 1、測驗代碼
- 2、補充:convertTo的用法
- 參考文獻
0、知識點

案例: 像素值越接近255越白,兩引數則是調整像素和對比度,
Api介面:

復習Vec3f :
Vec3f表示的是3通道float型別的 Vect,就相當于3通道float型別的影像(這是其中一個具體化),解釋可以從源代碼中看出來,
下面給出一個具體的例子:
Vec3f point = Vec3f(10,10,3.2);//Float, 3 components
Mat mat(3,3,CV_32FC3,);//3 channel matrix
Vec3f v3f = mat.at(y, x);//read color values for pixel (y,x)
這里注釋一下:Vec3f是一種資料型別,其是3通道的float,后面的mat.at(y, x)是訪問影像的一種方式,(可以從定義形式上看出來 int a=…)
對于mat的理解,可以認為mat.at是mat的一種訪問形式,其有點類似vector,
復習Vec3b:
Vec3b可以看作是vector<uchar, 3>,
簡單而言就是一個uchar型別的,長度為3的vector向量,
由于在OpenCV中,使用imread讀取到的Mat影像資料,都是用uchar型別的資料存盤,對于RGB三通道的影像,每個點的資料都是一個Vec3b型別的資料,使用at定位方法如下:
img.at(row, col)[0] = 255; // 這是指修改B通道資料
img.at(row, col)[1] = 255; // 這是指修改G通道資料
img.at(row, col)[2] = 255; // 這是指修改R通道資料
1、測驗代碼
創建一張跟原影像大小和型別一致的空白影像,像素值初始化為0;
saturate_cast(value)確保值在0-255之間;
Mat.at(y,x)[index] = value每個像素點每個通道賦值
測驗影像:

測驗代碼:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
#if 1
int main(int argc, char** argv) {
Mat src, dst;
//圖片路徑
src = imread("D:/CV2021/opencv_test0/Project1/test_img/40c.png");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_win[] = "input image";
//cvtColor(src, src, CV_BGR2GRAY); //灰度
namedWindow(input_win, CV_WINDOW_AUTOSIZE);
imshow(input_win, src);
// contrast and brigthtness changes
int height = src.rows;
int width = src.cols;
dst = Mat::zeros(src.size(), src.type());//影像初始化 BGR
float alpha = 1.2;
float beta = 30;
//Mat m1;
//src.convertTo(m1, CV_32F);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (src.channels() == 3) {
//RGB三通道
float b = src.at<Vec3b>(row, col)[0];// blue
float g = src.at<Vec3b>(row, col)[1]; // green
float r = src.at<Vec3b>(row, col)[2]; // red
// output:亮度和對比度處理
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
}
else if (src.channels() == 1) {
//灰度值
float v = src.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta);
}
}
}
char output_title[] = "contrast and brightness change demo";
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(output_title, dst);
waitKey(0);
return 0;
}
#endif
測驗結果:

2、補充:convertTo的用法
函式原型:
void Mat::convertTo( Mat& m, int rtype, double alpha=1, double beta=0 )
引數解釋:
m 目標矩陣,如果m的大小與原矩陣不一樣,或者資料型別與引數不匹配,那么在函式convertTo內部會先給m重新分配空間,
rtype 指定從原矩陣進行轉換后的資料型別,即目標矩陣m的資料型別,當然,矩陣m的通道數應該與原矩陣一樣的,如果rtype是負數,那么m矩陣的資料型別應該與原矩陣一樣,
alpha 縮放因子,默認值是1,即把原矩陣中的每一個元素都乘以alpha,
beta 增量,默認值是0,即把原矩陣中的每一個元素都乘以alpha,再加上beta,
功能
把一個矩陣從一種資料型別轉換到另一種資料型別,同時可以帶上縮放因子和增量,公式如下:
m(x,y)=saturate_cast(alpha*(*this)(x,y)+beta);
由于有資料型別的轉換,所以需要用saturate_cast來處理資料的溢位,
三通道測驗,測驗代碼:
Mat m1;
src.convertTo(m1, CV_32F);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (src.channels() == 3) {
//RGB三通道
float b = m1.at<Vec3f>(row, col)[0];// blue
float g = m1.at<Vec3f>(row, col)[1]; // green
float r = m1.at<Vec3f>(row, col)[2]; // red
// output:亮度和對比度處理
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
測驗結果:

在灰度基礎上,測驗代碼:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
#if 1
int main(int argc, char** argv) {
Mat src, dst;
//圖片路徑
src = imread("D:/CV2021/opencv_test0/Project1/test_img/40c.png");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_win[] = "input image";
cvtColor(src, src, CV_BGR2GRAY);
namedWindow(input_win, CV_WINDOW_AUTOSIZE);
imshow(input_win, src);
// contrast and brigthtness changes
int height = src.rows;
int width = src.cols;
dst = Mat::zeros(src.size(), src.type());//影像初始化 BGR
float alpha = 1.2;
float beta = 30;
Mat m1;
src.convertTo(m1, CV_32F);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (src.channels() == 3) {
//RGB三通道
float b = m1.at<Vec3f>(row, col)[0];// blue
float g = m1.at<Vec3f>(row, col)[1]; // green
float r = m1.at<Vec3f>(row, col)[2]; // red
// output:亮度和對比度處理
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
}
else if (src.channels() == 1) {
//灰度值
float v = src.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta);
}
}
}
char output_title[] = "contrast and brightness change demo";
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(output_title, dst);
waitKey(0);
return 0;
}
#endif
測驗結果:

去掉灰度,進行降低對比度的操作: float alpha = 0.2;測驗結果:

參考文獻
https://www.cnblogs.com/suubai/p/12485417.html
http://www.360doc.com/content/16/1202/09/35269117_611224795.shtml
https://blog.csdn.net/xiongwen_li/article/details/78523670
https://www.bbsmax.com/A/GBJrKeQK50/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301617.html
標籤:其他
