Как прочитать изображение с серой шкалой .tif с плавающей точкой в ​​openCV - PullRequest
2 голосов
/ 02 июля 2019

Я пытаюсь прочитать .tif или .tiff изображение с серой шкалой с плавающей точкой в ​​OpenCV.

Я могу читать и записывать обычные форматы файлов, такие как png, jpg и т. Д., Но я не могу читать с рабочего стола формат, который я никогда раньше не использовал, который является .tif или .tiff форматом.

Изображение : изображение, которое я пытаюсь прочитать, имеет следующие параметры: Размер:

size image

И ширина, и высота:

widthHeight image

После некоторой документации и различных источников я смог понять, что можно использовать функцию convertTo для преобразования между доступными типами данных, источник можно найти здесь .Однако это не сработало, и на самом деле у меня была ошибка компиляции:

OpenCV (3.4.1) Ошибка: утверждение не выполнено (size.width> 0 && size.height> 0) в imshow, файл /home/to/opencv/modules/highgui/src/window.cpp, строка 356 завершается, вызывается после создания экземпляра cv :: Exception what (): OpenCV (3.4.1) / home / to / opencv / modules/highgui/src/window.cpp:356: ошибка: (-215) size.width> 0 && size.height> 0 в функции imshow

Я использую следующий код:

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    Mat img = imread("/home/to/Desktop/example.tif");
    cv::imshow("source",img);
    Mat dst;  // destination image

    // check if we have RGB or grayscale image
    if (img.channels() == 3) {
        // convert 3-channel (RGB) 8-bit uchar image to 32 bit float
        img.convertTo(dst, CV_32FC3);
    }
    else if (img.channels() == 1) {
        // convert 1-chanel (grayscale) 8-bit uchar image to 32 bit float
        img.convertTo(dst, CV_32FC1);
    }

    // display output, note that to display dst image correctly
    // we have to divide each element of dst by 255 to keep
    // the pixel values in the range [0,1].
    cv::imshow("output",dst/255);
    waitKey();
}

Дополнительный пример, который я пытался заставить его работать, прямо из документации OpenCV, которую можно найти здесь , но с небольшой модификацией.Я прочитал из официальной документации , что опции IMREAD_ANYCOLOR | IMREAD_ANYDEPTH также должны быть активированы, и фактически это то, что я сделал во втором дополнительном испытании ниже:

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    String imageName( "/home/to/Desktop/example.tif" ); // by default
    if( argc > 1)
    {
        imageName = argv[1];
    }
Mat image;
Mat outImage;
image = imread( imageName, IMREAD_ANYCOLOR | IMREAD_ANYDEPTH ); // Read the file
if( image.empty() )                      // Check for invalid input
{
    cout <<  "Could not open or find the image" << std::endl ;
    return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.

resize(image, outImage, cv::Size(500,500));

imshow("orig", image);
imshow("resized", outImage);



// Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;

На этот раз компилятор работает безлюбая ошибка, но изображение не отображается, поскольку это можно увидеть на экране печати ниже:

image

ОБНОВЛЕНИЕ

Эторезультат после cv::resize

resized

ОБНОВЛЕНИЕ 2

Это результат после применения imshow("Display window", image*10);

5

Чего-то не хватает в официальной документации или что-то еще, что я забыл сделать?Спасибо, что пролили свет на эту проблему.

1 Ответ

1 голос
/ 03 июля 2019

Ваше изображение состоит из одного канала с 64-разрядными числами с плавающей запятой, который варьируется от -219.774 до -22.907.Я могу сказать, что используя tiffutil, который поставляется с libtiff:

tiffutil -verboseinfo  image.tif

TIFFReadDirectory: Warning, Unknown field with tag 33550 (0x830e) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 33922 (0x8482) encountered.
TIFFReadDirectory: Warning, Unknown field with tag 42113 (0xa481) encountered.
Directory at 0x256b3a2
  Image Width: 2277 Image Length: 2153
  Bits/Sample: 64
  Sample Format: IEEE floating point
  Compression Scheme: none
  Photometric Interpretation: "min-is-black"
  Samples/Pixel: 1
  Rows/Strip: 1
  Number of Strips: 2153
  Strips (Offset, ByteCount):
     17466, 18216
     35682, 18216
     53898, 18216
     ...
     ...

Я точно не знаю, что вы планируете делать, но в качестве первого удара вы можете просто добавить 220 к каждому пикселюи преобразовать в unsigned char, и ваш диапазон будет от 0 до 197, что идеально отображается:

enter image description here

Я действительно сделал это с помощью Python, потому что я быстреес этим, но C ++ будет следовать точно такой же формат:

import cv2

# Load image
img = cv2.imread('image.tif',cv2.IMREAD_UNCHANGED)

# Add 220 to all values, round to unsigned 8-bit and display
Image.fromarray((img+220).astype(np.uint8)).show()
...