2014-03-27 50 views
1

我目前正在研究一個程序,該程序應該拍攝LDR圖像並在圖像中乘以某個像素,以便它們的像素值將超過正常0-255(0 -1)像素值邊界。我編寫的程序可以這樣做,但我無法寫入圖像文件,因爲OpenCV中的imwrite()會將值返回到0-255(0-1) 的範圍內,如果它們大於255 。在openCv中寫入像素值大於1的浮動圖像

是否有任何人那裏誰知道如何與像素值大於255(1)

我的代碼看起來像這樣

Mat ApplySunValue(Mat InputImg) 
{ 
Mat Image1 = imread("/****/.jpg",CV_LOAD_IMAGE_COLOR); 

Mat outPutImage; 

Image1.convertTo(Image1, CV_32FC3); 

for(int x = 0; x < InputImg.cols; x++){ 
    for(int y = 0; y < InputImg.rows; y++){ 

     float blue = Image1.at<Vec3f>(y,x)[0] /255.0f; 
     float green = Image1.at<Vec3f>(y,x)[1] /255.0f; 
     float red = Image1.at<Vec3f>(y,x)[2] /255.0f ; 

     Image1.at<Vec3f>(y,x)[0] = blue; 
     Image1.at<Vec3f>(y,x)[1] = green; 
     Image1.at<Vec3f>(y,x)[2] = red; 

     int pixelValue = InputImg.at<uchar>(y,x); 

     if(pixelValue > 254){ 


      Image1.at<Vec3f>(y,x)[0] = blue * SunMultiplyer; 
      Image1.at<Vec3f>(y,x)[1] = green * SunMultiplyer; 
      Image1.at<Vec3f>(y,x)[2] = red * SunMultiplyer;  
     } 

    } 

} 

imwrite("/****/Nice.TIFF", Image1 * 255); 

namedWindow("Hej",CV_WINDOW_AUTOSIZE); 
imshow("hej", Image1); 



return InputImg; 
} 
+0

你有沒有考慮過使用OpenEXR? http://www.openexr.com http://stackoverflow.com/questions/2119099/using-exr-images-in-opencv –

+1

感謝您的回覆。是的,我已經考慮使用openexr,但我不斷收到此錯誤消息:ibC++ abi.dylib:終止與Iex :: EnosysExc類型的未捕獲異常:無法初始化信號量(函數未實現)。當試圖寫一個exr格式。 –

+0

您想保存文件以進行可視化還是僅用於存儲目的? – AldurDisciple

回答

2

爲了儲存目的,以下是更多的內存比XML/YAML替代有效(由於使用二進制格式的):

// Save the image data in binary format 
std::ofstream os(<filepath>,std::ios::out|std::ios::trunc|std::ios::binary); 
os << (int)image.rows << " " << (int)image.cols << " " << (int)image.type() << " "; 
os.write((char*)image.data,image.step.p[0]*image.rows); 
os.close(); 

然後可以加載圖像,如下所示:

// Load the image data from binary format 
std::ifstream is(<filepath>,std::ios::in|std::ios::binary); 
if(!is.is_open()) 
    return false; 
int rows,cols,type; 
is >> rows; is.ignore(1); 
is >> cols; is.ignore(1); 
is >> type; is.ignore(1); 
cv::Mat image; 
image.create(rows,cols,type); 
is.read((char*)image.data,image.step.p[0]*image.rows); 
is.close(); 

例如,無壓縮,一個1920x1200的浮點三通道圖像需要26 MB以二進制格式存儲時,而它需要129 MB存儲在YML格式時。由於對硬盤的訪問次數非常不同,因此此大小差異也會對運行時間產生影響。

現在,如果你想要的是可視化你的HDR圖像,你別無選擇,只能將其轉換爲LDR。這被稱爲「色調映射」(Wikipedia entry)。

+0

感謝您的回覆。不幸的是,我確實需要將HDR圖像可視化。我將嘗試弄清楚如何對圖像文件進行色調映射。 –

+0

@KristianMoesgaard HDR圖像可視化的最簡單方法是使用「線性色調映射」,即除以最大可能值(在您的情況下爲'SunMultiplyer')並乘以255.然而,就您的情況而言,這只是讓你回到輸入圖像... – AldurDisciple

2

據我知道寫一個浮點圖像,當opencv使用imwrite進行寫入,它使用圖像容器支持的格式進行寫入,默認情況下爲255. 但是,如果您只是將w ant來保存數據,你可以考慮將Mat對象寫入一個xml/yaml文件。

//Writing 
cv::FileStorage fs; 
fs.open(filename, cv::FileStorage::WRITE); 
fs<<"Nice"<<Image1; 

//Reading 
fs.open(filename, cv::FileStorage::READ); 
fs["Nice"]>>Image1; 

fs.release(); //Very Important