文章目錄
- 一、影像的加權混合
- 線性混合
- 二、對比度增強
一、影像的加權混合
線性混合
函式是將兩張相同大小,相同型別的圖片(疊加)線性融合的函式,可以實作圖片的特效,
影像的線性混合: g ( x ) = ( 1 ? α ) f 0 ( x ) + α f 1 ( x ) \mathrm{g}(x) = (1- \alpha)f_0(x)+ \alpha f_1(x) g(x)=(1?α)f0?(x)+αf1?(x)
-
void addWeighted(
-
InputArray
src1, 原陣列1
double alpha, 原陣列1的權重值 : α \alpha α
InputArray src2, 原陣列2
double beta, 陣列2 的權重值,( 1 ? α 1-\alpha 1?α)
double gamma, 加權和后的影像的偏移量(標量)
OutputArray dst, 輸出的陣列(公式如上)
int dtype = -1 輸出陣列的深度,有默認值-1,即src1.depth()
);
頭檔案 quick_opencv.h:宣告類與公共函式
#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;
class QuickDemo {
public:
...
void mix_image_Demo(Mat& image1, Mat& image2); //新增方法
void image_contrast_Demo(Mat& image1);
};
主函式呼叫該類的公共成員函式
#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat src1 = imread("D:\\Desktop\\ttt.png");
Mat src2 = imread("D:\\Desktop\\uuu.png");
if (src1.empty()) {
printf("Could not load images1...\n");
return -1;
}
if (src2.empty()) {
printf("Could not load images2...\n");
return -1;
}
imshow("input1", src1);
imshow("input2", src2);
QuickDemo qk;
qk.mix_image_Demo(src1, src2);
qk.image_contrast_Demo(src1);
waitKey(0);
destroyAllWindows();
return 0;
}
源檔案 quick_demo.cpp:實作類與公共函式
#include <quick_opencv.h>
#include <opencv2/dnn.hpp>
using namespace cv;
using namespace std;
void QuickDemo::mix_image_Demo(Mat& image1, Mat& image2) {
double alpha = 0.5;
if (image1.size() != image2.size()) {
cout << "影像尺寸不匹配" << endl;
}
Mat dst;
addWeighted(image1, alpha, image2, (1 - alpha), 0, dst, -1);
imshow("dst", dst);
}

二、對比度增強
通過影像的像素變換(點操作)調整影像的亮度和對比度:
g
(
i
,
j
)
=
α
f
(
i
,
j
)
+
β
\mathrm{g}(i,j) = \alpha f(i,j)+ \beta
g(i,j)=αf(i,j)+β 其中
β
\beta
β 為增益變數
源檔案 quick_demo.cpp:實作類與公共函式
void QuickDemo::image_contrast_Demo(Mat& image) {
int width = image.cols;
int height = image.rows;
int channel = image.channels();
Mat dst_at = Mat::zeros(image.size(), image.type());
Mat dst_ptr = dst_at.clone();
float alpha = 1.5;
float beta = 10.0;
//轉成灰度圖,浮點數圖(計算精度更高),
Mat image32f,image8u;
cvtColor(image.clone(), image8u, COLOR_BGR2GRAY);
image.convertTo(image32f, CV_32F);
Mat dst_8u = Mat::zeros(image8u.size(), image8u.type());
int channel8u = image8u.channels();
if (channel8u == 1) {
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
uchar v = image8u.at<uchar>(h, w);
dst_8u.at<uchar>(h, w) = saturate_cast<uchar>(v * alpha + beta);
}
}
}
double time0 = static_cast<double>(getTickCount()); // 計時
if (channel == 3) {
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
dst_at.at<Vec3b>(h, w)[0] = saturate_cast<uchar>(image32f.at<Vec3f>(h, w)[0] * alpha + beta);
dst_at.at<Vec3b>(h, w)[1] = saturate_cast<uchar>(image32f.at<Vec3f>(h, w)[1] * alpha + beta);
dst_at.at<Vec3b>(h, w)[2] = saturate_cast<uchar>(image32f.at<Vec3f>(h, w)[2] * alpha + beta);
}
}
}
double time1 = static_cast<double>(getTickCount()); // 計時
if (channel == 3) {
for (int h = 0; h < height; h++) {
float* current_row = image32f.ptr<float>(h);
uchar* dst_current_row = dst_ptr.ptr<uchar>(h);
for (int w = 0; w < width; w++) {
*dst_current_row++ = saturate_cast<uchar>(*current_row++ * alpha + beta);
*dst_current_row++ = saturate_cast<uchar>(*current_row++ * alpha + beta);
*dst_current_row++ = saturate_cast<uchar>(*current_row++ * alpha + beta);
}
}
}
double time2 = static_cast<double>(getTickCount()); // 計時
cout << "time1-time0=" << (time1 - time0)/getTickFrequency() << endl;
cout << "time2-time1=" << (time2 - time1)/ getTickFrequency() << endl;
imshow("image8u原圖", image8u);
imshow("image8u對比度增強at", dst_8u);
imshow("image對比度增強at", dst_at);
imshow("image對比度增強ptr", dst_ptr);
}
兩種像素對比度增強,使用at與ptr兩種像素遍歷方式,ptr遍歷方式速度大約快一半,(單位:秒)



關于手動調節 亮度與對比對,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290536.html
標籤:其他
