美文网首页
[05]16位图像转8位图像

[05]16位图像转8位图像

作者: 豚大叔的小屋 | 来源:发表于2023-02-23 18:51 被阅读0次

    1.原理
    1)16位图像
    16位图像的每个像素点的像素值都由16位的二进制数表示,每个像素点的颜色有 2^16 = 65536 种可能。也就是说,图像的颜色区间被划分成了2^16 = 65536份。
    2)8位图像
    8位图像的每个像素点的像素值都由8位的二进制数表示,每个像素点的颜色有 2^8 = 256 种可能图像的颜色区间被划分成了2^8 = 256份。
    3)数据类型
    ushort 为无符号16位整数,占2个字节,取值范围在0~65,535之间。
    uchar 为无符号8位,占1个字节,取值范围在0~255之间。
    2.转化
    16位到8位,是高精度到低精度的转换,必然造成信息的丢失,信息丢失是不可避免的
    1)错误思维:
    将16位转换成8位是将区间 [0,65535] 映射到 [0,255] ,错误的认为16位的图像像素值分布在 [0,65535] 。
    2)正确思维----相对好方式
    取图像像素值最小值到最大值区间映射到[0,255]。
    int main()
    {
    Mat img = imread("test.tif", CV_LOAD_IMAGE_UNCHANGED);//加载图像
    int width = img.cols;//图片宽度
    int height = img.rows;//图片高度
    Mat dst = Mat::zeros(height, width, CV_8UC1);//生成空目标图
    double minv = 0.0, maxv = 0.0;
    double* minp = &minv;
    double* maxp = &maxv;
    minMaxIdx(img, minp, maxp); //取得像素值最大值和最小值
    //用指针访问像素,速度更快
    ushort *p_img;
    uchar *p_dst;
    for (int i = 0; i < height; i++)
    {
    p_img = img.ptr<ushort>(i);//获取每行首地址
    p_dst = dst.ptr<uchar>(i);
    for (int j = 0; j < width; ++j)
    {
    p_dst[j] = (p_img[j] - minv) / (maxv - minv) * 255;
    //下面是失真较大的转换方法
    //int temp = img.at<ushort>(i, j);
    //dst.at<uchar>(i, j) = temp;
    }
    }
    imshow("8bit image", dst);
    imwrite("task1_8bit.jpg", dst);
    waitKey(0);
    system("pause");
    return 0;
    }

    相关文章

      网友评论

          本文标题:[05]16位图像转8位图像

          本文链接:https://www.haomeiwen.com/subject/txltldtx.html