2015-04-23 3 views
-1

Я использую OpenCV2.4.8.2 в Mac OS 10.9.5. У меня есть следующий фрагмент кода:OpenCV-2.4.8.2: imshow отличается от imwrite

static void compute_weights(const vector<Mat>& images, vector<Mat>& weights) 
{ 
    weights.clear(); 
    for (int i = 0; i < images.size(); i++) { 
     Mat image = images[i]; 
     Mat mask = Mat::zeros(image.size(), CV_32F); 
     int x_start = (i == 0) ? 0 : image.cols/2; 
     int y_start = 0; 
     int width = image.cols/2; 
     int height = image.rows; 
     Mat roi = mask(Rect(x_start,y_start,width,height)); // Set Roi 
     roi.setTo(1); 
     weights.push_back(mask); 
    } 
} 

static void blend(const vector<Mat>& inputImages, Mat& outputImage) 
{ 
    int maxPyrIndex = 6; 
    vector<Mat> weights; 
    compute_weights(inputImages, weights); 

    // Find the fused pyramid: 
    vector<Mat> fused_pyramid; 
    for (int i = 0; i < inputImages.size(); i++) { 
     Mat image = inputImages[i]; 
     // Build Gaussian Pyramid for Weights 
     vector<Mat> weight_gaussian_pyramid; 
     buildPyramid(weights[i], weight_gaussian_pyramid, maxPyrIndex); 

     // Build Laplacian Pyramid for original image 
     Mat float_image; 
     inputImages[i].convertTo(float_image, CV_32FC3, 1.0/255.0); 
     vector<Mat> orig_guassian_pyramid; 
     vector<Mat> orig_laplacian_pyramid; 
     buildPyramid(float_image, orig_guassian_pyramid, maxPyrIndex); 
     for (int j = 0; j < orig_guassian_pyramid.size() - 1; j++) { 
      Mat sized_up; 
      pyrUp(orig_guassian_pyramid[j+1], sized_up, Size(orig_guassian_pyramid[j].cols, orig_guassian_pyramid[j].rows)); 
      orig_laplacian_pyramid.push_back(orig_guassian_pyramid[j] - sized_up); 
     } 
     // Last Lapalcian layer is the same as the Gaussian layer 
      orig_laplacian_pyramid.push_back(orig_guassian_pyramid[orig_guassian_pyramid.size()-1]); 

     // Convolve laplacian original with guassian weights 
     vector<Mat> convolved; 
     for (int j = 0; j < maxPyrIndex + 1; j++) { 
      // Create 3 channels for weight gaussian pyramid as well 
      vector<Mat> gaussian_3d_vec; 
      for (int k = 0; k < 3; k++) { 
       gaussian_3d_vec.push_back(weight_gaussian_pyramid[j]); 
      } 
      Mat gaussian_3d; 
      merge(gaussian_3d_vec, gaussian_3d); 

      //Mat convolved_result = weight_gaussian_pyramid[j].clone(); 
      Mat convolved_result = gaussian_3d.clone(); 

      multiply(gaussian_3d, orig_laplacian_pyramid[j], convolved_result); 
      convolved.push_back(convolved_result); 
     } 

     if (i == 0) { 
      fused_pyramid = convolved; 
     } else { 
      for (int j = 0; j < maxPyrIndex + 1; j++) { 
       fused_pyramid[j] += convolved[j]; 
      } 
     } 
    } 
    // Blending 
    for (int i = (int)fused_pyramid.size()-1; i > 0; i--) { 
     Mat sized_up; 
     pyrUp(fused_pyramid[i], sized_up, Size(fused_pyramid[i-1].cols, fused_pyramid[i-1].rows)); 
     fused_pyramid[i-1] += sized_up; 
    } 

    Mat final_color_bgr; 
    fused_pyramid[0].convertTo(final_color_bgr, CV_32F, 255); 
    final_color_bgr.copyTo(outputImage); 

    imshow("final", outputImage); 
    waitKey(0); 
    imwrite(outputImagePath, outputImage); 
} 

Этот код делает некоторые основные пирамиды смешивания 2 изображений. Основные проблемы связаны с imshow и imwrite в последней строке. Они дали мне совершенно разные результаты. Я прошу прощения за отображение такого длинного/грязного кода, но я боюсь, что эта разница исходит из некоторых других частей кода, которые могут впоследствии повлиять на imshow и imwrite.

На первом изображении показан результат imwrite, а на втором изображении показан результат imshow на основе приведенного кода. Я совершенно смущен, почему это так. imwrite's result imshow's result

Я также заметил, что, когда я делаю это:

Mat float_image; 
inputImages[i].convertTo(float_image, CV_32FC3, 1.0/255.0); 
imshow("float image", float_image); 
imshow("orig image", image); 

Они показывают то же самое, что они оба показывают ту же картину в исходном изображении (RGB в изображении).

+0

imshow для значений поплавка означает 0 = черный и 1 = белый, поэтому полностью белое изображение имеет, вероятно, значения интенсивности в неправильном масштабе. – Micka

+0

Привет Мика, спасибо за ответ. Но как получилось, что imwrite в порядке? Вы правильно относитесь к шкале. Если я масштабирую его на 1 ближе к концу, imshow в порядке, но imwrite все черное ... –

+0

возможно, imwrite и imshow использовать разные предположения о диапазоне значений;) какое расширение файла вы пишете? Возможно, это расширение файла даже может обрабатывать float напрямую или просто выполняет преобразование типа без масштабирования значений (в то время как imshow умножает значения float на 255!). – Micka

ответ

4

функциональность IMWRITE

По умолчанию imwrite, преобразует входное изображение в только 8-битный (или 16-битовое беззнаковое (CV_16U) в случае PNG, JPEG 2000, и TIFF) одноканальные или 3-канальный (с порядком канала BGR) изображения можно сохранить с помощью этой функции. В любом формате, который вы подаете для imwrite, он слепо преобразуется в CV_8U с диапазоном 0 (черный) - 255 (белый) в формате BGR.

IMSHOW - проблема

Поэтому, когда заметил вашу функцию, fused_pyramid[0].convertTo(final_color_bgr, CV_32F, 255); fused_pyramid уже под циновки типа 21 (с плавающей точкой CV_32F). Вы пытались преобразовать в плавающую точку с коэффициентом масштабирования 255. Этот масштабный коэффициент 255 вызвал проблему @ imshow. Вместо того, чтобы визуализировать, вы можете напрямую подключаться к fused_pyramid без преобразования, поскольку он уже масштабируется с плавающей точкой между 0.0 (черный) - 1.0 (белый).

Надеюсь, это поможет.

+1

Спасибо, Шрирам. Ваше объяснение было очень проницательным. Я никогда не повторю эту ошибку. –

Смежные вопросы