Я хочу прочитать 16-битный Tiff, а затем преобразовать его, чтобы показать его как 8-битный.
void ImgProc::Load_Image_2xTiff_16bit_G(Mat *Mat_A_in, Mat *Mat_B_in, string file_name)
{
vector<Mat> vec_Mat;
vec_Mat.reserve(2);
imreadmulti(file_name, vec_Mat);
*Mat_A_in = vec_Mat[0];
*Mat_B_in = vec_Mat[1];
}
void ImgProc::Convert_Mat16_2_QIm8(QImage *QIm_Out, Mat *Mat_In, double scale_factor)
{
unsigned int rows = Mat_In->rows;
unsigned int cols = Mat_In->cols;
*QIm_Out = QImage(cols, rows, QImage::Format_Grayscale8);
unsigned char* line_QIm;
if (!Mat_In->data)
return;
for(unsigned int y = 0; y < rows; y++)
{
line_QIm = QIm_Out->scanLine(y);
for(unsigned int x = 0; x < cols; x++)
{
line_QIm[x] = (unsigned char)(Mat_In->at<ushort>(y, x) * scale_factor);
}
}
}
Когда я использую Mat_In->at<ushort>(y, x)
(читать 16 бит) abort() has been called
, То же самое происходит, если я использую <short>
вместо.
Когда я использую Mat_In->at<uchar>(y, x)
(читай 8 бит) это работает, но отсекает информацию без масштабирования. Это проявляется в виде «черных дыр» в более ярких областях изображения, вероятно, из-за эффекта переполнения.
Я думаю, что я должен упомянуть, что камера, которая сделала снимки, использует только 14-битную глубину.
Я столкнулся с такой же проблемой.
Следующий код является решением, которое я использовал для исправления этого случая.
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <QImage>
int main(void)
{
//Read the 16 bit per pixel image.
cv::Mat I = cv::imread('16BitsPerPixelImage.tiff',cv::IMREAD_ANYDEPTH|cv::IMREAD_ANYCOLOR);
//Convert from 16 bit per pixel to 8 bit per pixel using a min max normalization and store it a 8 bit per pixel.
cv::normalize(I,I,0.,255.,cv::NORM_MINMAX,CV_8U);
// Then actualy the easiest way to convert it to a QImage is to save a temporary file and open it using QT functions.
// PNG use a compression without loss algorithm.
cv::imwrite("/tmp/convert16to8.png",I);
QImage QI;
QI.load("/tmp/convert16to8.png");
return EXIT_SUCCESS;
}
Других решений пока нет …