OpenCV 實現圖片HDR功能


簡介

  本篇主要是利用三張圖片:過曝(相機設置exposure+1)、正常(相機設置exposure+0)、欠曝(相機設置exposure-1),來合成一張在亮出和暗處細節都清晰
的圖片,來簡易實現圖片的HDR功能。

具體實現

實現代碼

 1 #include <opencv2/core/core.hpp>                                                                                                     
 2 #include <opencv2/highgui/highgui.hpp>
 3 #include <math.h>
 4 #include <string.h>
 5 #include <opencv/cv.h>
 6 #include <stdio.h>
 7 #include "opencv2/photo/photo.hpp"
 8  
 9 using namespace cv; 10  
11 char highpicName[20]; 12 char normalpicName[20]; 13 char lowpicName[20]; 14 Mat mat1, mat2, mat3, dst_mat, tmp_mat; 15 int highWidth, highHeight; 16 int normalWidth, normalHeight; 17 int lowWidth, lowHeight; 18 IplImage src1, src2, src3, dst_src, tmp_src; 19 double weight=0.5; 20  
21  
22 void hdrCale(Mat pic1, Mat pic2, Mat pic3){ 23     int i, j; 24  CvScalar s1, s2, s3; 25  
26  
27     src1 = pic1; 28     src2 = pic2; 29     src3 = pic3; 30     dst_src = dst_mat; 31     tmp_src = tmp_mat; 32  
33     cvCvtColor(&src2, &tmp_src, CV_BGR2GRAY); 34     for(i=0; i< normalWidth; i++){ 35         for(j=0; j<normalHeight; j++){ 36             s1 = cvGet2D(&src1, i, j); 37             s2 = cvGet2D(&tmp_src, i, j); 38             s3 = cvGet2D(&src3, i, j); 39             weight = 0.5 + (127 - s2.val[0]) * 0.002; 40             s3.val[0] = (s1.val[0] * weight) + (s3.val[0] * (1-weight)); 41             s3.val[1] = (s1.val[1] * weight) + (s3.val[1] * (1-weight)); 42             s3.val[2] = (s1.val[2] * weight) + (s3.val[2] * (1-weight)); 43             cvSet2D(&dst_src, i, j, s3); 44  } 45  } 46 } 47  
48  
49 int main(int argc, char *argv[]){ 50     if(argc < 4){ 51         printf("Please input high exposure/normal exposure/low exposure picture!\n"); 52         return -1; 53  } 54     memcpy(highpicName, argv[1], sizeof(argv[1])); 55     memcpy(normalpicName, argv[2], sizeof(argv[2])); 56     memcpy(lowpicName, argv[3], sizeof(argv[3])); 57     mat1 = imread(argv[1]); 58     mat2 = imread(argv[2]); 59     mat3 = imread(argv[3]); 60     highWidth = mat1.rows; 61     highHeight = mat1.cols; 62     normalWidth = mat2.rows; 63     normalHeight = mat2.cols; 64     lowWidth = mat3.rows; 65     lowHeight = mat3.cols; 66     dst_mat = Mat(normalWidth, normalHeight, CV_8UC3, cv::Scalar(0, 0, 0)); 67     tmp_mat = Mat(normalWidth, normalHeight, CV_8UC1, cv::Scalar(0, 0, 0)); 68  
69  hdrCale(mat1, mat2, mat3); 70  
71     imshow("normal", mat2); 72     imshow("HDR", dst_mat); 73     imwrite("HDR.jpg", dst_mat); 74     cv::waitKey(0); 75     return 0; 76 }

代碼講解
  1、首先進行相對應的初始化操作:運行軟件時候,需要傳入三張圖片,順序上分別是:過曝、正常、欠曝。打開這三張圖片,保存在mat1、mat2、mat3
中,注意這三張圖片必須大小一致。接着獲取到圖片的width和height。最后創建兩張空白圖片:tmp_mat和dst_mat。

 1         if(argc < 4){  2         printf("Please input high exposure/normal exposure/low exposure picture!\n");  3         return -1;  4  }  5     memcpy(highpicName, argv[1], sizeof(argv[1]));  6     memcpy(normalpicName, argv[2], sizeof(argv[2]));  7     memcpy(lowpicName, argv[3], sizeof(argv[3]));  8     mat1 = imread(argv[1]);  9     mat2 = imread(argv[2]); 10     mat3 = imread(argv[3]); 11     highWidth = mat1.rows; 12     highHeight = mat1.cols; 13     normalWidth = mat2.rows; 14     normalHeight = mat2.cols; 15     lowWidth = mat3.rows; 16     lowHeight = mat3.cols; 17     dst_mat = Mat(normalWidth, normalHeight, CV_8UC3, cv::Scalar(0, 0, 0)); 18     tmp_mat = Mat(normalWidth, normalHeight, CV_8UC1, cv::Scalar(0, 0, 0));

  2、接着進入到HDR的算法處理:對應的處理很簡單,主要就是根據就是權重,把過曝和欠曝圖片合成到dst_mat中。
具體做法:循環依次打開三張圖片的同一位置像素,用正常曝光圖片像素,利用公式:weight = 0.5 + (127 - s2.val[0]) * 0.002;
來獲得使用過曝、欠曝像素合成到dst_mat中對應使用的權值。接着:s3.val[0] = (s1.val[0] * weight) + (s3.val[0] * (1-weight));
計算出合成像素值之后,寫入到dst_mat對應的坐標位置。進而生成HDR照片。

 1 void hdrCale(Mat pic1, Mat pic2, Mat pic3){  2     int i, j;  3  CvScalar s1, s2, s3;  4  
 5     src1 = pic1;  6     src2 = pic2;  7     src3 = pic3;  8     dst_src = dst_mat;  9     tmp_src = tmp_mat; 10  
11     cvCvtColor(&src2, &tmp_src, CV_BGR2GRAY); 12     for(i=0; i< normalWidth; i++){ 13         for(j=0; j<normalHeight; j++){ 14             s1 = cvGet2D(&src1, i, j); 15             s2 = cvGet2D(&tmp_src, i, j); 16             s3 = cvGet2D(&src3, i, j); 17             weight = 0.5 + (127 - s2.val[0]) * 0.002; 18             s3.val[0] = (s1.val[0] * weight) + (s3.val[0] * (1-weight)); 19             s3.val[1] = (s1.val[1] * weight) + (s3.val[1] * (1-weight)); 20             s3.val[2] = (s1.val[2] * weight) + (s3.val[2] * (1-weight)); 21             cvSet2D(&dst_src, i, j, s3); 22  } 23  } 24 }
 3、最后將正常照片和HDR照片顯示初戀,並將hdr照片保存下來。
1     imshow("normal", mat2); 2     imshow("HDR", dst_mat); 3     imwrite("HDR.jpg", dst_mat); 4     cv::waitKey(0);

效果演示

 對應的效果演示如下:
    過曝圖像:

正常圖像

欠曝圖像:

HDR圖像

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM