color a grayscale image with opencv
Asked Answered
C

2

5

i'm using openNI for some project with kinect sensor. i'd like to color the users pixels given with the depth map. now i have pixels that goes from white to black, but i want from red to black. i've tried with alpha blending, but my result is only that i have pixels from pink to black because i add (with addWeight) red+white = pink.

this is my actual code:

layers = device.getDepth().clone();
cvtColor(layers, layers, CV_GRAY2BGR);

Mat red = Mat(240,320, CV_8UC3, Scalar(255,0,0));
Mat red_body; // = Mat::zeros(240,320, CV_8UC3);
red.copyTo(red_body, device.getUserMask());

addWeighted(red_body, 0.8, layers, 0.5, 0.0, layers);

where device.getDepth() returns a cv::Mat with depth map and device.getUserMask() returns a cv::Mat with user pixels (only white pixels)

some advice?

EDIT: one more thing: thanks to sammy answer i've done it. but actually i don't have values exactly from 0 to 255, but from (for example) 123-220.

i'm going to find minimum and maximum via a simple for loop (are there better way?), and how can i map my values from min-max to 0-255 ?

Clance answered 21/5, 2012 at 17:3 Comment(1)
Did you -unselect- Sammy's answer?? It was a very nice answer. I hadn't understood how you wanted to colorize your greyscale image. Mul is a nice solution. I think it is very rude to add another part to your question, un-select the previously correct answer, and wait for more. Not to mention that max-min and scaling are easy to look up in the references.Conto
C
5

First, OpenCV's default color format is BGR not RGB. So, your code for creating the red image should be

Mat red = Mat(240,320, CV_8UC3, Scalar(0,0,255));

For red to black color map, you can use element wise multiplication instead of alpha blending

Mat out = red_body.mul(layers, 1.0/255);

You can find the min and max values of a matrix M using

double minVal, maxVal;
minMaxLoc(M, &minVal, &maxVal, 0, 0);

You can then subtract the minValue and scale with a factor

double factor = 255.0/(maxVal - minVal);    
 M = factor*(M -minValue)
Crossstitch answered 21/5, 2012 at 18:15 Comment(2)
I wondered about that BGR too. But nkint says the result was pink. Go figure.Conto
yeah i'm using cv::Mat but i wrapped them in gl texture for drawing.. well.. actually the framework i'm using do itClance
C
3

Kinda clumsy and slow, but maybe split layers, copy red_body (make it a one channel Mat, not 3) to the red channel, merge them back into layers?

Get the same effect, but much faster (in place) with reshape:

layers = device.getDepth().clone();
cvtColor(layers, layers, CV_GRAY2BGR);

Mat red = Mat(240,320, CV_8UC1, Scalar(255)); // One channel
Mat red_body; 
red.copyTo(red_body, device.getUserMask());

Mat flatLayer = layers.reshape(1,240*320); // presumed dimensions of layer
red_body.reshape(0,240*320).copyTo(flatLayer.col(0));

// layers now has the red from red_body
Conto answered 21/5, 2012 at 17:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.