C++ 读取OpenCV Mat 16位至QImage 8位灰度 我想做什么 文件:TIFF,2页,灰度,16位 OpenCV:2x材质,灰度,16位(CV_16UC1) Qt:2倍图像,灰度,8比特(格式为灰色8)

C++ 读取OpenCV Mat 16位至QImage 8位灰度 我想做什么 文件:TIFF,2页,灰度,16位 OpenCV:2x材质,灰度,16位(CV_16UC1) Qt:2倍图像,灰度,8比特(格式为灰色8),c++,qt,opencv,bit,converters,C++,Qt,Opencv,Bit,Converters,我想读取16位Tiff,然后将其转换为8位 阅读 void ImgProc::加载\u图像\u 2xTiff\u 16位\u G(Mat*Mat\u A\u in,Mat*Mat\u B\u in,字符串文件名) { 向量向量矩阵; 车辆材料储备(2); imreadmulti(文件名,vec\u Mat); *Mat_A_in=vec_Mat[0]; *Mat_B_in=vec_Mat[1]; } 转变 void ImgProc::Convert_Mat16_2_QIm8(QImage*

我想读取16位Tiff,然后将其转换为8位

阅读
void ImgProc::加载\u图像\u 2xTiff\u 16位\u G(Mat*Mat\u A\u in,Mat*Mat\u B\u in,字符串文件名)
{  
向量向量矩阵;
车辆材料储备(2);
imreadmulti(文件名,vec\u 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,双比例因子)
{
无符号整数行=Mat_In->rows;
无符号整数cols=Mat_In->cols;
*QIm_Out=QImage(列、行、QImage::Format_Grayscale8);
无符号字符*line_QIm;
如果(!Mat_In->data)
回来
for(无符号整数y=0;y扫描线(y);
for(无符号整数x=0;xat(y,x)*比例因子);
}
}
}
问题 当我使用
Mat_In->at(y,x)
(读取16位)时,它会崩溃,调用了
abort()。如果我改用
,也会发生同样的情况

当我使用
Mat_In->at(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;
    }
#包括
#包括
#包括
#包括
内部主(空)
{
//读取每像素16位的图像。
cv::Mat I=cv::imread('16BitsPerPixelImage.tiff',cv::imread_ANYDEPTH | cv::imread_ANYCOLOR);
//使用最小-最大规格化从每像素16位转换为每像素8位,并将其存储为每像素8位。
标准化(I,I,0,255,cv::NORM_MINMAX,cv_8U);
//实际上,将其转换为QImage的最简单方法是保存一个临时文件并使用QT函数打开它。
//PNG使用无损耗压缩算法。
cv::imwrite(“/tmp/convert16to8.png”,I);
齐玛格齐;
QI.load(“/tmp/convert16to8.png”);
返回退出成功;
}

中的
材质的实际值是多少为什么不使用(然后只使用整个原始缓冲区,而不是逐像素循环)返回
0
。我尝试使用
cv::Mat::convertTo
,但失败了,所以我尝试了这种方法。我还喜欢,我确切地知道那里发生了什么,并且可以随时进行操作。
0
的类型对应于
CV_8U
,这意味着图像已经是8比特了。这就解释了崩溃的原因(我希望它能通过一半的行)。能否提供产生此问题的示例图像?演示如何读取图像文件。OpenCV读取为8UC3类型default@Micka我的读取方法如上所示。很好的提示,谢谢。我将尝试找出如何将其读取为16位。添加
cv::IMREAD_ANYDEPTH | cv::IMREAD_ANYCOLOR
作为
imreadmulti
的标志解决了这个问题,我的其余代码仍按原样工作。非常感谢你!现在我可以开始做一些很酷的事情了。
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);
        }
    }
}
   #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;
    }