Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

opencv: how to save float array as an image

Tags:

c++

opencv

I'm absolutly new to c++ and the opencv library. I was browsing through stackoverflow and also searched the web, but couldn't find an answer to my question.

How can I save a float array to an image in c++? Currently (as an exercise) I'm just manually converting the image to grayscale (although I read that this can be done with opencv).

Later on I plan to do some filter operations and other pixel operations. That's why I want to use a float-array (of size 512*512).

Here's the code. All I know is, that the float array has to be converted to int or char or uint8 or cv::Mat, so that it can be saved as a .png, but I didnt't know how to.

Any hints or links are highly appreciated.

#include <stdio.h>
#include <opencv2/highgui/highgui.hpp>

int main(void)
{
  // load in image using opencv and convert to char
  cv::Mat myImg = cv::imread("~/Lenna.png", CV_LOAD_IMAGE_COLOR);
  unsigned char *img = (unsigned char*)(myImg.data); //somehow only works for unsigned char and not for float (SegFault)

  float *r = new float[512*512]; 
  float *g = new float[512*512]; 
  float *b = new float[512*512]; 
  float *gray = new float[512*512];


  // 3*iCol, bc every pixel takes 3 bytes (one for R channel/B channel /G channel).
  // see http://answers.opencv.org/question/2531/image-data-processing-in-cvmat/
  // faster to loop through rows first and then through colums (bc MAT stored in row-major order)
  uint iPix = 0;
  for(int iRow=0; iRow<512 ;iRow++){
    for(int iCol=0; iCol<512 ;iCol++){
      b[iPix] = (float) img[myImg.step * iRow + 3*iCol     ];
      g[iPix] = (float) img[myImg.step * iRow + 3*iCol + 1 ];
      r[iPix] = (float) img[myImg.step * iRow + 3*iCol + 2 ];
      gray[iPix] = (float) 0.0722*b[iPix] + 0.2126*r[iPix] + 0.7152*g[iPix];
      iPix++;
    }
  }


  //write image to file (NOT WORKING!)
  cv::imwrite("~/imgOut.png",  (cv::Mat) gray);
}
like image 273
user3524709 Avatar asked Apr 11 '14 17:04

user3524709


1 Answers

You can use

cv::imwrite("~/imgOut.bmp",  cv::Mat(512, 512, CV_32FC1, gray));

P.S.: I saved it to BMP instead to make it work because, for imwrite(), only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function.

like image 110
herohuyongtao Avatar answered Sep 20 '22 15:09

herohuyongtao