简体   繁体   中英

Change 16 bit grayscale image to Color Image using OpenCV and C++

I am newbie in openCV and trying to convert the image of 16 bit grayscale image to a color image using color palatte. I have done this operation when I have 8 bit image but now I am fetching the image frame from the thermal camera which give me 16 bit frame and I can't convert that to 8 bit because it decreases the quality of the image which is useless. In 8 bit image I have use LUT function for doing this task.

My Lookup table Code for 8 bit image

    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);

In above code palette is a color palatte and im is a grayscale image. I am reading the color of palette and put that in lut and then using LUT function just making a colored image.

So, can anyone help me how I can do the above with 16 bit image. Thanks in Advance.

When I run this code I got execption which says:-

I am getting a exception which says Assertion failed ((lutcn == cn || lutcn == 1) && _lut.total() == 256 && _lut.isContinuous() && (depth == 0 || depth == 1)) in cv:: LUT

Code to generate a 8 bit color image from 16 bit grayscale. Maps white to red, and black to blue.

#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;
}

LUT quick and dirty:

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM