Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

color a grayscale image with opencv

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 ?

like image 254
nkint Avatar asked May 21 '12 17:05

nkint


2 Answers

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)
like image 99
Sammy Avatar answered Sep 30 '22 09:09

Sammy


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
like image 36
Bobbi Bennett Avatar answered Sep 30 '22 07:09

Bobbi Bennett