使用OpenCV和C ++将16位灰度图像更改为彩色图像

时间:2018-06-04 05:48:20

标签: c++ opencv image-processing

我是openCV中的新手,并尝试使用彩色图片将16 bit grayscale图片的图片转换为彩色图片。当我有8 bit图像时,我已完成此操作但现在我从热像仪中取出图像帧,这给我16位帧,我无法将其转换为8 bit,因为它会减少图像的质量是无用的。在8 bit图片中,我使用LUT函数执行此任务。

我的查找表8位图像的代码

    Mat palette, im;
    palette = imread("1.bmp", IMREAD_COLOR);
    im = imread("C:\\Users\\Chandrapal Singh\\Desktop\\New folder\\IMG_0_10_34_45_2018_1.bmp", IMREAD_GRAYSCALE);
    im.convertTo(im, CV_16U);
    cvtColor(im.clone(), im, COLOR_GRAY2BGR);
    double scale = (double)palette.rows / 256;
    uchar b[256], g[256], r[256];
    int i = 0;
    for (double x = 1; x <= palette.rows;) {

        b[i] = palette.at<Vec3b>((int)x, palette.cols / 2)[0];
        g[i] = palette.at<Vec3b>((int)x, palette.cols / 2)[1];
        r[i] = palette.at<Vec3b>((int)x, palette.cols / 2)[2];
        i++;
        x += scale;
    }

    Mat channels[] = { Mat(256,1, CV_8U, b), Mat(256,1, CV_8U, g), Mat(256,1, CV_8U, r) };
    Mat lut;
    cv::merge(channels, 3, lut);

    Mat color;
    cv::LUT(im, lut, color);

在上面的代码palette中是一个颜色调色板,im是一个灰度图像。我正在阅读调色板的颜色并将其放在lut中,然后使用LUT函数制作彩色图像。

那么,任何人都可以帮助我如何使用16位图像完成上述操作。在此先感谢。

当我运行此代码时,我得到了一个说法: -

我收到了Assertion failed ((lutcn == cn || lutcn == 1) && _lut.total() == 256 && _lut.isContinuous() && (depth == 0 || depth == 1)) in cv:: LUT

的异常

2 个答案:

答案 0 :(得分:0)

从16位灰度生成8位彩色图像的代码。将白色映射为红色,将黑色映射为蓝色。

#include "opencv2/imgcodecs.hpp"

using namespace cv;
using namespace std;

float a;

Vec3b getBGR(float _val) //unique values only if a >= ~ 0.3 ~= 300 / float(1024);
{   //from https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
    float H = a*_val;
    float S = 1;
    float V = 1;

    double      hh, p, q, t, ff;
    long        i;
    Vec3b BGR;

    if (S <= 0.0)
    {       
        BGR[2] = V * 255;//R
        BGR[1] = V * 255;//G
        BGR[0] = V * 255;//B
        return BGR;
    }
    hh = H;
    if (hh >= 360.0) hh = 0.0;// not sure about that
    hh /= 60.0;
    i = (long)hh;
    ff = hh - i;
    p = V * (1.0 - S);
    q = V * (1.0 - (S * ff));
    t = V * (1.0 - (S * (1.0 - ff)));

    switch (i)
    {
    case 0:
        BGR[2] = V * 255;
        BGR[1] = t * 255;
        BGR[0] = p * 255;
        break;
    case 1:
        BGR[2] = q * 255;
        BGR[1] = V * 255;
        BGR[0] = p * 255;
        break;
    case 2:
        BGR[2] = p * 255;
        BGR[1] = V * 255;
        BGR[0] = t * 255;
        break;

    case 3:
        BGR[2] = p * 255;
        BGR[1] = q * 255;
        BGR[0] = V * 255;
        break;
    case 4:
        BGR[2] = t * 255;
        BGR[1] = p * 255;
        BGR[0] = V * 255;
        break;
    case 5:
    default:
        BGR[2] = V * 255;
        BGR[1] = p * 255;
        BGR[0] = q * 255;
        break;
    }

    return BGR;
}

void color_from_gray(Mat& gray, Mat& color)
{   
    double minVal, maxVal;
    minMaxLoc(gray, &minVal, &maxVal);

    //HSV range from 0 (red) to 240 (blue)
    a = 240 / (maxVal - minVal);//global variable!

    MatIterator_<ushort> it, end;
    MatIterator_<Vec3b> iit = color.begin<Vec3b>();//not the most efficient way to iterate
    for (it = gray.begin<ushort>(), end = gray.end<ushort>(); it != end; ++it, ++iit) 
        *iit = getBGR(maxVal - *it);
}

int main(int argc, char** argv)
{
    Mat gray = imread("gray.tif", IMREAD_ANYDEPTH);

    Mat color(gray.size(), CV_8UC3);

    color_from_gray(gray, color);

    imwrite("color.tif", color);

    return 0;
}

答案 1 :(得分:0)

快速而肮脏:

Mat gray = imread("gray.tif", IMREAD_ANYDEPTH);
Mat palette = imread("palette.png", IMREAD_COLOR);

Mat color(gray.size(), CV_8UC3);
Vec3b lut[65536];

double scale = (double)palette.rows / 65536;
int i = 0;
for (double x = 1; x <= palette.rows;)
{
    lut[i] = palette.at<Vec3b>((int)x, 0);
    i++;
    x += scale;
}

for (int j = 0; j < gray.rows; j++)//rows
    for (int i = 0; i < gray.cols; i++)//cols
        color.at<Vec3b>(j, i) = lut[gray.at<ushort>(j, i)];

imwrite("color_lut.tif", color);