Use the V channel to provide masking information, indicating invalid depths.

This commit is contained in:
Andrzej Kapolka 2013-07-30 13:42:29 -07:00
parent 3c437076a7
commit f8ba1c4be1
2 changed files with 52 additions and 20 deletions

View file

@ -569,9 +569,9 @@ void FrameGrabber::grabFrame() {
ydest[0] = (tl[redIndex] * Y_RED_WEIGHT + tl[1] * Y_GREEN_WEIGHT + tl[blueIndex] * Y_BLUE_WEIGHT) >> 8;
ydest[1] = (tr[redIndex] * Y_RED_WEIGHT + tr[1] * Y_GREEN_WEIGHT + tr[blueIndex] * Y_BLUE_WEIGHT) >> 8;
ydest[ENCODED_FACE_WIDTH] = (bl[redIndex] * Y_RED_WEIGHT + bl[greenIndex] *
ydest[vpxImage.stride[0]] = (bl[redIndex] * Y_RED_WEIGHT + bl[greenIndex] *
Y_GREEN_WEIGHT + bl[blueIndex] * Y_BLUE_WEIGHT) >> 8;
ydest[ENCODED_FACE_WIDTH + 1] = (br[redIndex] * Y_RED_WEIGHT + br[greenIndex] *
ydest[vpxImage.stride[0] + 1] = (br[redIndex] * Y_RED_WEIGHT + br[greenIndex] *
Y_GREEN_WEIGHT + br[blueIndex] * Y_BLUE_WEIGHT) >> 8;
ydest += 2;
@ -616,26 +616,37 @@ void FrameGrabber::grabFrame() {
glm::mix(mean, _smoothedMeanFaceDepth, DEPTH_OFFSET_SMOOTHING);
// convert from 11 to 8 bits for preview/local display
const double EIGHT_BIT_MIDPOINT = 128.0;
const uchar EIGHT_BIT_MIDPOINT = 128;
double depthOffset = EIGHT_BIT_MIDPOINT - _smoothedMeanFaceDepth;
depth.convertTo(_grayDepthFrame, CV_8UC1, 1.0, depthOffset);
// likewise for the encoded representation
uchar* yline = (uchar*)_encodedFace.data() + vpxImage.stride[0] * ENCODED_FACE_HEIGHT;
src = _faceDepth.ptr<ushort>();
const char EIGHT_BIT_MAXIMUM = 255;
for (int i = 0; i < ENCODED_FACE_HEIGHT; i++) {
uchar* yline = vpxImage.planes[0] + vpxImage.stride[0] * ENCODED_FACE_HEIGHT;
uchar* vline = vpxImage.planes[1] + vpxImage.stride[1] * (ENCODED_FACE_HEIGHT / 2);
const uchar EIGHT_BIT_MAXIMUM = 255;
for (int i = 0; i < ENCODED_FACE_HEIGHT; i += 2) {
uchar* ydest = yline;
for (int j = 0; j < ENCODED_FACE_WIDTH; j++) {
ushort depth = *src++;
if (depth == ELEVEN_BIT_MINIMUM) {
*ydest++ = EIGHT_BIT_MAXIMUM;
} else {
*ydest++ = saturate_cast<uchar>(depth + depthOffset);
}
uchar* vdest = vline;
for (int j = 0; j < ENCODED_FACE_WIDTH; j += 2) {
ushort tl = *_faceDepth.ptr<ushort>(i, j);
ushort tr = *_faceDepth.ptr<ushort>(i, j + 1);
ushort bl = *_faceDepth.ptr<ushort>(i + 1, j);
ushort br = *_faceDepth.ptr<ushort>(i + 1, j + 1);
uchar mask = EIGHT_BIT_MIDPOINT;
ydest[0] = (tl == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MAXIMUM) : saturate_cast<uchar>(tl + depthOffset);
ydest[1] = (tr == ELEVEN_BIT_MINIMUM) ? (mask = EIGHT_BIT_MAXIMUM) : saturate_cast<uchar>(tr + depthOffset);
ydest[vpxImage.stride[0]] = (bl == ELEVEN_BIT_MINIMUM) ?
(mask = EIGHT_BIT_MAXIMUM) : saturate_cast<uchar>(bl + depthOffset);
ydest[vpxImage.stride[0] + 1] = (br == ELEVEN_BIT_MINIMUM) ?
(mask = EIGHT_BIT_MAXIMUM) : saturate_cast<uchar>(br + depthOffset);
ydest += 2;
*vdest++ = mask;
}
yline += vpxImage.stride[0];
yline += vpxImage.stride[0] * 2;
vline += vpxImage.stride[1];
}
}

View file

@ -147,10 +147,31 @@ int Face::processVideoMessage(unsigned char* packetData, size_t dataBytes) {
if (image->d_h > imageHeight) {
// if the height is greater than the width, we have depth data
depth.create(imageHeight, image->d_w, CV_8UC1);
uchar* src = image->planes[0] + image->stride[0] * imageHeight;
for (int i = 0; i < imageHeight; i++) {
memcpy(depth.ptr(i), src, image->d_w);
src += image->stride[0];
uchar* yline = image->planes[0] + image->stride[0] * imageHeight;
uchar* vline = image->planes[1] + image->stride[1] * (imageHeight / 2);
const uchar EIGHT_BIT_MAXIMUM = 255;
const uchar MASK_THRESHOLD = 192;
for (int i = 0; i < imageHeight; i += 2) {
uchar* ysrc = yline;
uchar* vsrc = vline;
for (int j = 0; j < image->d_w; j += 2) {
if (*vsrc++ >= MASK_THRESHOLD) {
*depth.ptr(i, j) = EIGHT_BIT_MAXIMUM;
*depth.ptr(i, j + 1) = EIGHT_BIT_MAXIMUM;
*depth.ptr(i + 1, j) = EIGHT_BIT_MAXIMUM;
*depth.ptr(i + 1, j + 1) = EIGHT_BIT_MAXIMUM;
} else {
*depth.ptr(i, j) = ysrc[0];
*depth.ptr(i, j + 1) = ysrc[1];
*depth.ptr(i + 1, j) = ysrc[image->stride[0]];
*depth.ptr(i + 1, j + 1) = ysrc[image->stride[0] + 1];
}
ysrc += 2;
}
yline += image->stride[0] * 2;
vline += image->stride[1];
}
}
QMetaObject::invokeMethod(this, "setFrame", Q_ARG(cv::Mat, color),