HDR【openCV实现】
生活随笔
收集整理的這篇文章主要介紹了
HDR【openCV实现】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本篇主要是利用三張圖片:過曝(相機設(shè)置exposure+1)、正常(相機設(shè)置exposure+0)、欠曝(相機設(shè)置exposure-1),來合成一張在亮出和暗處細(xì)節(jié)都清晰
的圖片,來簡易實現(xiàn)圖片的HDR功能。
具體實現(xiàn)
實現(xiàn)代碼
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <math.h> #include <string.h> #include <opencv/cv.h> #include <stdio.h> #include "opencv2/photo/photo.hpp"using namespace cv;char highpicName[20]; char normalpicName[20]; char lowpicName[20]; Mat mat1, mat2, mat3, dst_mat, tmp_mat; int highWidth, highHeight; int normalWidth, normalHeight; int lowWidth, lowHeight; IplImage src1, src2, src3, dst_src, tmp_src; double weight=0.5;void hdrCale(Mat pic1, Mat pic2, Mat pic3){int i, j;CvScalar s1, s2, s3;src1 = pic1;src2 = pic2;src3 = pic3;dst_src = dst_mat;tmp_src = tmp_mat;cvCvtColor(&src2, &tmp_src, CV_BGR2GRAY);for(i=0; i< normalWidth; i++){for(j=0; j<normalHeight; j++){s1 = cvGet2D(&src1, i, j);s2 = cvGet2D(&tmp_src, i, j);s3 = cvGet2D(&src3, i, j);weight = 0.5 + (127 - s2.val[0]) * 0.002;s3.val[0] = (s1.val[0] * weight) + (s3.val[0] * (1-weight));s3.val[1] = (s1.val[1] * weight) + (s3.val[1] * (1-weight));s3.val[2] = (s1.val[2] * weight) + (s3.val[2] * (1-weight));cvSet2D(&dst_src, i, j, s3);} } }int main(int argc, char *argv[]){if(argc < 4){printf("Please input high exposure/normal exposure/low exposure picture!\n");return -1; }memcpy(highpicName, argv[1], sizeof(argv[1]));memcpy(normalpicName, argv[2], sizeof(argv[2]));memcpy(lowpicName, argv[3], sizeof(argv[3]));mat1 = imread(argv[1]);mat2 = imread(argv[2]);mat3 = imread(argv[3]);highWidth = mat1.rows;highHeight = mat1.cols;normalWidth = mat2.rows;normalHeight = mat2.cols;lowWidth = mat3.rows;lowHeight = mat3.cols;dst_mat = Mat(normalWidth, normalHeight, CV_8UC3, cv::Scalar(0, 0, 0));tmp_mat = Mat(normalWidth, normalHeight, CV_8UC1, cv::Scalar(0, 0, 0));hdrCale(mat1, mat2, mat3);imshow("normal", mat2);imshow("HDR", dst_mat);imwrite("HDR.jpg", dst_mat);cv::waitKey(0);return 0; }代碼講解
1、首先進(jìn)行相對應(yīng)的初始化操作:運行軟件時候,需要傳入三張圖片,順序上分別是:過曝、正常、欠曝。打開這三張圖片,保存在mat1、mat2、mat3 中,注意這三張圖片必須大小一致。接著獲取到圖片的width和height。最后創(chuàng)建兩張空白圖片:tmp_mat和dst_mat。 if(argc < 4){printf("Please input high exposure/normal exposure/low exposure picture!\n");return -1; }memcpy(highpicName, argv[1], sizeof(argv[1]));memcpy(normalpicName, argv[2], sizeof(argv[2]));memcpy(lowpicName, argv[3], sizeof(argv[3]));mat1 = imread(argv[1]);mat2 = imread(argv[2]);mat3 = imread(argv[3]);highWidth = mat1.rows;highHeight = mat1.cols;normalWidth = mat2.rows;normalHeight = mat2.cols;lowWidth = mat3.rows;lowHeight = mat3.cols;dst_mat = Mat(normalWidth, normalHeight, CV_8UC3, cv::Scalar(0, 0, 0));tmp_mat = Mat(normalWidth, normalHeight, CV_8UC1, cv::Scalar(0, 0, 0)); 2、接著進(jìn)入到HDR的算法處理:對應(yīng)的處理很簡單,主要就是根據(jù)就是權(quán)重,把過曝和欠曝圖片合成到dst_mat中。 具體做法:循環(huán)依次打開三張圖片的同一位置像素,用正常曝光圖片像素,利用公式:weight = 0.5 + (127 - s2.val[0]) * 0.002;來獲得使用過曝、欠曝像素合成到dst_mat中對應(yīng)使用的權(quán)值。接著:s3.val[0] = (s1.val[0] * weight) + (s3.val[0] * (1-weight));計算出合成像素值之后,寫入到dst_mat對應(yīng)的坐標(biāo)位置。進(jìn)而生成HDR照片。 void hdrCale(Mat pic1, Mat pic2, Mat pic3){int i, j;CvScalar s1, s2, s3;src1 = pic1;src2 = pic2;src3 = pic3;dst_src = dst_mat;tmp_src = tmp_mat;cvCvtColor(&src2, &tmp_src, CV_BGR2GRAY);for(i=0; i< normalWidth; i++){for(j=0; j<normalHeight; j++){s1 = cvGet2D(&src1, i, j);s2 = cvGet2D(&tmp_src, i, j);s3 = cvGet2D(&src3, i, j);weight = 0.5 + (127 - s2.val[0]) * 0.002;s3.val[0] = (s1.val[0] * weight) + (s3.val[0] * (1-weight));s3.val[1] = (s1.val[1] * weight) + (s3.val[1] * (1-weight));s3.val[2] = (s1.val[2] * weight) + (s3.val[2] * (1-weight));cvSet2D(&dst_src, i, j, s3);} } } 3、最后將正常照片和HDR照片顯示初戀,并將hdr照片保存下來。 imshow("normal", mat2);imshow("HDR", dst_mat);imwrite("HDR.jpg", dst_mat);cv::waitKey(0); 新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的HDR【openCV实现】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于citrix 负载及WI的一些问题
- 下一篇: 数据中台、数据仓库和数据湖传统的区别