How to get one picture from YUV frame in C++ - c++

In C++ i have an
LPBYTE pYUV;
It's contains a YUV data. I used this code to save it to an image file named Original.bmp
BITMAPINFOHEADER* bi = new BITMAPINFOHEADER;
bi->biSize = sizeof(BITMAPINFOHEADER);
bi->biWidth = pVSI->nWidth;
bi->biHeight = pVSI->nHeight;
bi->biPlanes = 1;
bi->biBitCount = 24;
bi->biCompression = 0;
bi->biSizeImage = 0;
bi->biXPelsPerMeter = 2835;
bi->biYPelsPerMeter = 2835;
bi->biClrUsed = 0;
bi->biClrImportant = 0;
BITMAPINFO* bmi = (BITMAPINFO*)bi;
HDC dc = ::GetDC(NULL);
HBITMAP bmp = CreateDIBitmap(dc, bi, CBM_INIT, pYUV, bmi, DIB_RGB_COLORS);
::ReleaseDC(NULL, dc);
CBitmapEx bitmap;
bitmap.Load(bmp);
bitmap.Save(_T("Original.bmp"));
When i open the Original.bmp, it's look like this
It's have too many same picture in the image.How do i process the LPBYTE pYUV to make one picture in the Original.bmp file ?
ps: I can do this by draw it to DirectX by this code.
But i don't know how to write it to image file
LPBYTE apDst[3] = { 0 };
apDst[0] = (LPBYTE)pSurface; // Y
apDst[1] = (LPBYTE)pSurface + nPitch*nH; // U
apDst[2] = (LPBYTE)pSurface + nPitch*nH * 5 / 4; //V
LPBYTE apSrc[3] = { 0 };
apSrc[0] = pYUV; // Y
apSrc[1] = pYUV + nW*nH * 5 / 4; // V
apSrc[2] = pYUV + nW*nH; // U
int anPch[3] = { 0 };
anPch[0] = nW; // Y
anPch[1] = nW / 2; // V
anPch[2] = nW / 2; // U
LPBYTE pDst, pSrc;
int i, k;
int w, h, p;
int div[3] = { 1, 2, 2 };
for (k = 0; k < 3; k++)
{
pSrc = apSrc[k];
pDst = apDst[k];
w = nW / div[k]; // w means the width of one row
h = nH / div[k]; // h means the rows
p = nPitch / div[k];
for (i = 0; i < h; i++)
{
memcpy(pDst, pSrc, w);
pDst += p;
pSrc += anPch[k];
}
}
and It work like this
Thanks in advance.

Related

Capture mouse cursor and apply transparency masking in Win32

Im trying to capture mouse cursor using windows API GetCursorInfo and taking in to CURSORINFO structure after I reading ICONINFO using GetIconInfo so I will get hbmMask and hbmColor bitmap
The hbmMask bitmap is first applied with an AND raster operation, then the hbmColor bitmap is applied with an XOR raster operation. This results in an opaque cursor and a transparent background but this is not happening in my POC complete code in below example.
After doing AND raster on mask data and XOR on color data the final result will be cursor and covered with white colored rectangle 32*32.
void save_as_bitmap(unsigned char *bitmap_data, int rowPitch, int width, int height, char *filename)
{
// A file is created, this is where we will save the screen capture.
FILE *f;
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
//Make the size negative if the image is upside down.
bi.biHeight = -height;
//There is only one plane in RGB color space where as 3 planes in YUV.
bi.biPlanes = 1;
//In windows RGB, 8 bit - depth for each of R, G, B and alpha.
bi.biBitCount = 32;
//We are not compressing the image.
bi.biCompression = BI_RGB;
// The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// rowPitch = the size of the row in bytes.
DWORD dwSizeofImage = rowPitch * height;
// Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwSizeofImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//Offset to where the actual bitmap bits start.
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
//Size of the file
bmfHeader.bfSize = dwSizeofDIB;
//bfType must always be BM for Bitmaps
bmfHeader.bfType = 0x4D42; //BM
// TODO: Handle getting current directory
fopen_s(&f, filename, "wb");
DWORD dwBytesWritten = 0;
dwBytesWritten += fwrite(&bmfHeader, sizeof(BITMAPFILEHEADER), 1, f);
dwBytesWritten += fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, f);
dwBytesWritten += fwrite(bitmap_data, 1, dwSizeofImage, f);
fclose(f);
}
//ST484 : HBIMAPtoBYTE : Convert BITMAP to BYTE array.
std::vector<BYTE> HBIMAPtoBYTE( HBITMAP hBitmap,
int &hBitmapSize,
bool &bResult,
int &nWidth,
int &nHeight )
{
bResult = true;
BITMAP bmp;
if (!GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bmp))
{
DeleteObject(hBitmap);
bResult = false;
}
int rpcbiPlanes = 32;
BITMAPINFO info;
memset(&info, 0, sizeof(BITMAPINFO));
info.bmiHeader.biSize = sizeof(info.bmiHeader);
info.bmiHeader.biWidth = bmp.bmWidth;
info.bmiHeader.biHeight = -bmp.bmHeight;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = rpcbiPlanes;
info.bmiHeader.biCompression= BI_RGB;
size_t pixelSize = info.bmiHeader.biBitCount / 8;
size_t scanlineSize = (pixelSize * info.bmiHeader.biWidth + 3) & ~3;
size_t bitmapSize = bmp.bmHeight * scanlineSize;
hBitmapSize = bitmapSize;
nWidth = bmp.bmWidth;
nHeight = bmp.bmHeight;
std::vector<BYTE> pixels(bitmapSize);
HDC hdc = ::GetDC(NULL);
if(!GetDIBits(hdc, hBitmap, 0, bmp.bmHeight, &pixels[0], &info, DIB_RGB_COLORS))
{
hBitmapSize = 0;
bResult = false;
}
return pixels;
}
// getHCursor : Capture cursor.
CURSORINFO getHCursor()
{
CURSORINFO cursorInfo;
cursorInfo.cbSize = sizeof(CURSORINFO);
if (GetCursorInfo(&cursorInfo) == 0)
{
MessageBox(NULL, _T("Exception : GetCursorInfo creation failed"),_T("message"),MB_OK|MB_SYSTEMMODAL);
cursorInfo.hCursor = NULL;
return cursorInfo;
}
return cursorInfo;
}
//Main Call
int _tmain(int argc, _TCHAR* argv[])
{
int CountP = 0;
while (true)
{
CURSORINFO CursorInfo = getHCursor();
if (CursorInfo.hCursor == NULL)
{
::Sleep(MinSleep);
continue;
}
ICONINFO iconInfo;
if (!GetIconInfo(CursorInfo.hCursor, &iconInfo))
{
MessageBox(NULL, _T("Exception : GetIconInfo creation failed"),_T("message"),MB_OK|MB_SYSTEMMODAL);
::Sleep(MinSleep);
}
std::vector<BYTE> bColorBitmap;
std::vector<BYTE> bMaskBitmap;
std::vector<BYTE> bDestBitmap;
int sz_hbmColor = 0;
int sz_hbmMask = 0;
int sz_hbDest = 0;
int nWidth = 0;
int nHeight = 0;
bool hbmColor_result = false;
bool hbmMask_result = false;
bool hbmDest_result = false;
int rpcbiPlanes = 32;
bool isColorShape = (iconInfo.hbmColor != NULL);
// read mask and color in to byte vector.
bColorBitmap = HBIMAPtoBYTE(iconInfo.hbmColor,sz_hbmColor,hbmColor_result,nWidth,nHeight);
bMaskBitmap = HBIMAPtoBYTE(iconInfo.hbmMask,sz_hbmMask,hbmMask_result,nWidth,nHeight);
//Create Dummy bitmap using width and height filled with black color.
HBITMAP desBitmap = CreateBitmap(nWidth,nHeight,1,rpcbiPlanes,NULL);
if(desBitmap != NULL)
{
// read dummy bitmap in to byte vector.
bDestBitmap = HBIMAPtoBYTE(desBitmap,sz_hbDest,hbmDest_result,nWidth,nHeight);
}
//the mask bitmap is first applied with an AND raster operation.
for(int i = 0; i < nHeight ; i++)
{
for(int j = 0; j < nWidth; j++)
{
bDestBitmap[i*4*nWidth + j*4 ] &= bMaskBitmap[i*4*nWidth + j*4 ];
bDestBitmap[i*4*nWidth + j*4 + 1] &= bMaskBitmap[i*4*nWidth + j*4 + 1];
bDestBitmap[i*4*nWidth + j*4 + 2] &= bMaskBitmap[i*4*nWidth + j*4 + 2];
bDestBitmap[i*4*nWidth + j*4 + 3] &= bMaskBitmap[i*4*nWidth + j*4 + 3];
}
}
//then the color bitmap is applied with an XOR raster operation.
for(int i = 0; i < nHeight ; i++)
{
for(int j = 0; j < nWidth; j++)
{
bDestBitmap[i*4*nWidth + j*4 ] ^= bColorBitmap[i*4*nWidth + j*4 ];
bDestBitmap[i*4*nWidth + j*4 + 1] ^= bColorBitmap[i*4*nWidth + j*4 + 1];
bDestBitmap[i*4*nWidth + j*4 + 2] ^= bColorBitmap[i*4*nWidth + j*4 + 2];
bDestBitmap[i*4*nWidth + j*4 + 3] ^= bColorBitmap[i*4*nWidth + j*4 + 3];
}
}
//Save Color bitmap.
sprintf_s(file_name,"C:\\Test\\captured\\Cursor_%d.bmp", CountP);
save_as_bitmap(&(bDestBitmap[0]), nWidth*4, nWidth, nHeight, file_name);
CountP++;
Sleep(MaxSleep);
}
return 0;
}
After saving cursor getting image like this
Finally I found excellent result using windows API.
Include comctl32.lib in to your project
HIMAGELIST iCursorList=ImageList_Create(nWidth,nHeight,ILC_COLOR32|ILC_MASK,8,8);
ImageList_AddMasked(iCursorList,iconInfo.hbmColor,000000);
DeleteObject(iconInfo.hbmColor);
TRANSPARENT_HICON = ImageList_GetIcon(iCursorList,0,ILD_TRANSPARENT);
1 ) Create ImageList_Create using width, height, ILC_COLOR32|ILC_MASK
2 ) Add bitmap in to ImageList_AddMasked and apply which color you want to make transparent, 000000 are black color in my code.
3 ) Get transparent icon from ImageList_GetIcon.

MediaFoundation + VP8 + Color Formats

My ultimate goal is to add video support to my Virtual Class application. My method is:
Capture frames using Media Foundation
Encode with VP8 using LibVPX
Transmit with UDP
Decode at the receipient site
Show frames in a Window
The first problem arises with my WebCam's supported color encodings. The webcam Media Types contain only MFVideoFormat_NV12. My first debugging attempt saves the receiving image to a bitmap so I can test it is correctly captured (error handling removed):
HRESULT CAP::StartRecord(HWND hh, CComPtr<IMFMediaSource> src)
{
MFCreateSourceReaderFromMediaSource(src, 0, &sr);
CComPtr<IMFMediaType> fmt;
sr->GetCurrentMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM,&fmt);
LogMediaType(fmt); // Shows: MFVideoFormat_NV12
auto [wi, he] = WidthHeight(fmt);
for (;;)
{
DWORD streamIndex = 0, flags = 0;
LONGLONG llTimeStamp = 0;
CComPtr<IMFSample> pSample;
hr = sr->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,0,&streamIndex,&flags,&llTimeStamp,&pSample);
if (FAILED(hr))
break;
if (!pSample)
continue;
CComPtr<IMFMediaBuffer> bu;
pSample->ConvertToContiguousBuffer(&bu);
SaveSampleNV12(bu, wi, he);
}
...
}
SaveSampleNV12 uses code from here to convert NV12 to RGB, then:
void SaveSampleNV12(CComPtr<IMFMediaBuffer> mm, int width32, int height32)
{
DWORD le = 0;
mm->GetCurrentLength(&le);
BYTE *pDatad = NULL;
auto hr = mm->Lock(&pDatad, NULL, NULL);
vector<char> rgb(1000000);
NV12ToRGB((BYTE*)rgb.data(), pDatad, width32, height32);
mm->Unlock();
HANDLE file;
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER fileInfo;
DWORD write = 0;
auto df = L"r:\\f.bmp";
file = CreateFile(df.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); //Sets up the new bmp to be written to
int bits = 24;
fileHeader.bfType = 19778; //Sets our type to BM or bmp
fileHeader.bfSize = sizeof(fileHeader.bfOffBits) + sizeof(RGBTRIPLE); //Sets the size equal to the size of the header struct
fileHeader.bfReserved1 = 0; //sets the reserves to 0
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //Sets offbits equal to the size of file and info header
fileInfo.biSize = sizeof(BITMAPINFOHEADER);
fileInfo.biWidth = width32;
fileInfo.biHeight = height32;
fileInfo.biPlanes = 1;
fileInfo.biBitCount = bits;
fileInfo.biCompression = BI_RGB;
fileInfo.biSizeImage = width32 * height32 * (bits / 8);
fileInfo.biXPelsPerMeter = 0;// 2400;
fileInfo.biYPelsPerMeter = 0;// 2400;
fileInfo.biClrImportant = 0;
fileInfo.biClrUsed = 0;
WriteFile(file, &fileHeader, sizeof(fileHeader), &write, NULL);
WriteFile(file, &fileInfo, sizeof(fileInfo), &write, NULL);
unsigned char* ptrIn = (unsigned char*)rgb.data();
int rgbs = width32 * height32 * (bits / 8);
vector<char> d2(rgbs);
unsigned char* ptrOut = (unsigned char*)d2.data();
for (int i = 0; i < (width32*height32) / 2; ++i)
{
int y0 = ptrIn[0];
int u0 = ptrIn[1];
int y1 = ptrIn[2];
int v0 = ptrIn[3];
ptrIn += 4;
int c = y0 - 16;
int d = u0 - 128;
int e = v0 - 128;
int bb = clip((298 * c + 516 * d + 128) >> 8); // blue
int gg = clip((298 * c - 100 * d - 208 * e + 128) >> 8); // green
int rr = clip((298 * c + 409 * e + 128) >> 8); // red
ptrOut[0] = bb;
ptrOut[1] = gg;
ptrOut[2] = rr;
c = y1 - 16;
ptrOut[3] = clip((298 * c + 516 * d + 128) >> 8); // blue
ptrOut[4] = clip((298 * c - 100 * d - 208 * e + 128) >> 8); // green
ptrOut[5] = clip((298 * c + 409 * e + 128) >> 8); // red
ptrOut += 6;
}
unsigned char* cc = (unsigned char*)d2.data();
WriteFile(file, cc, rgbs, &write, NULL);
CloseHandle(file);
}
This returns a weird full of Pink image. Something I'm doing wrong, but what?
Thanks a lot.
The solution is to use IMFTransform to tranform between various color spaces.

Why is bmp created as not transparent?

I have following code which creates transparent bmp image and saves it to clipboard. After this I tried to copy this to Photoshop or office, Gimp. But image is not transparent:
#include <Windows.h>
#include <iostream>
#include <Wingdi.h>
#include <algorithm>
using namespace std;
pair<int, HGLOBAL> dibv5_img(void)
{
const DWORD width = 100;
const DWORD height = 100;
BITMAPV5HEADER header = {0};
header.bV5Size = sizeof(BITMAPV5HEADER);
header.bV5Width = width;
header.bV5Height = -height;
header.bV5Planes = 1;
header.bV5BitCount = 32;
header.bV5Compression = BI_BITFIELDS;
header.bV5SizeImage = header.bV5Width * header.bV5Height * header.bV5BitCount / 8;
header.bV5CSType = LCS_WINDOWS_COLOR_SPACE;
header.bV5Intent = LCS_GM_IMAGES;
header.bV5BlueMask = 0x000000FF;
header.bV5GreenMask = 0x0000FF00;
header.bV5RedMask = 0x00FF0000;
header.bV5AlphaMask = 0xFF000000;
DWORD masks[3];
masks[0] = header.bV5BlueMask;
masks[1] = header.bV5GreenMask;
masks[2] = header.bV5AlphaMask;
DWORD pixels[width * height];
for (DWORD i = 0; i < height; ++i)
for (DWORD j = 0; j < width; ++j)
pixels[i * width + j] = 0;
for (DWORD i = height / 4; i < 3 * height / 4; ++i)
for (DWORD j = 0; j < width; ++j)
pixels[i * width + j] = (masks[0] | header.bV5AlphaMask) & 0xFFFFFFFF;
HGLOBAL hmem = GlobalAlloc(GHND | GMEM_DDESHARE, header.bV5Size + sizeof(DWORD) * (3 + width * height));
PVOID local_pointer = GlobalLock(hmem);
memcpy(local_pointer, &header, sizeof(BITMAPV5HEADER));
memcpy(reinterpret_cast<unsigned char*>(local_pointer) + sizeof(BITMAPV5HEADER), masks, sizeof(DWORD) * 3);
memcpy(reinterpret_cast<unsigned char*>(local_pointer) + sizeof(BITMAPV5HEADER) + sizeof(DWORD) * 3, pixels,
sizeof(DWORD) * width * height);
GlobalUnlock(hmem);
return pair<int, HGLOBAL>(CF_DIBV5, hmem);
}
int main(void)
{
cout << sizeof(DWORD) << endl;
if (!OpenClipboard(0))
return 1;
if (!EmptyClipboard())
return 1;
const auto data = dibv5_img();
SetClipboardData(data.first, data.second);
if (!CloseClipboard())
return 1;
return 0;
}
Output in all apps is following:

load cv::mat to faster rcnn blob

Currently I am working with Faster RCNN using C++. I am trying to load cv Mat object (color image) to the net_->blob_by_name("data"). I follow the given instruction here https://github.com/YihangLou/FasterRCNN-Encapsulation-Cplusplus but the result is really bad:
I didn't change anything from the original code. So I suspect loading data to blob might be the issue.
Code:
float im_info[3];
float data_buf[height*width*3];
float *boxes = NULL;
float *pred = NULL;
float *pred_per_class = NULL;
float *sorted_pred_cls = NULL;
int *keep = NULL;
const float* bbox_delt;
const float* rois;
const float* pred_cls;
int num;
for (int h = 0; h < cv_img.rows; ++h )
{
for (int w = 0; w < cv_img.cols; ++w)
{
cv_new.at<cv::Vec3f>(cv::Point(w, h))[0] = float(cv_img.at<cv::Vec3b>(cv::Point(w, h))[0])-float(102.9801);
cv_new.at<cv::Vec3f>(cv::Point(w, h))[1] = float(cv_img.at<cv::Vec3b>(cv::Point(w, h))[1])-float(115.9465);
cv_new.at<cv::Vec3f>(cv::Point(w, h))[2] = float(cv_img.at<cv::Vec3b>(cv::Point(w, h))[2])-float(122.7717);
}
}
cv::resize(cv_new, cv_resized, cv::Size(width, height));
im_info[0] = cv_resized.rows;
im_info[1] = cv_resized.cols;
im_info[2] = img_scale;
for (int h = 0; h < height; ++h )
{
for (int w = 0; w < width; ++w)
{
data_buf[(0*height+h)*width+w] = float(cv_resized.at<cv::Vec3f>(cv::Point(w, h))[0]);
data_buf[(1*height+h)*width+w] = float(cv_resized.at<cv::Vec3f>(cv::Point(w, h))[1]);
data_buf[(2*height+h)*width+w] = float(cv_resized.at<cv::Vec3f>(cv::Point(w, h))[2]);
}
}
net_->blob_by_name("data")->Reshape(1, 3, height, width);
net_->blob_by_name("data")->set_cpu_data(data_buf);
net_->blob_by_name("im_info")->set_cpu_data(im_info);
net_->ForwardFrom(0);
bbox_delt = net_->blob_by_name("bbox_pred")->cpu_data();
num = net_->blob_by_name("rois")->num();
Any advices ?
Can you please modify the code and check ...
cv::resize(cv_new, cv_resized, cv::Size(width, height));
im_info[0] = cv_resized.rows;
im_info[1] = cv_resized.cols;
im_info[2] = img_scale;
net_->blob_by_name("data")->Reshape(1, 3, height, width);
const shared_ptr<Blob<float> >& data_blob = net_->blob_by_name("data");
float* data_buf = data_blob->mutable_cpu_data();
for (int h = 0; h < height; ++h )
{
for (int w = 0; w < width; ++w)
{
data_buf[(0*height+h)*width+w] = float(cv_resized.at<cv::Vec3f> cv::Point(w, h))[0]);
data_buf[(1*height+h)*width+w] = float(cv_resized.at<cv::Vec3f>(cv::Point(w, h))[1]);
data_buf[(2*height+h)*width+w] = float(cv_resized.at<cv::Vec3f>(cv::Point(w, h))[2]);
}
}
net_->Forward();

Displaying Kinect streams using OpenCV (C++)

I'm trying to get every frame of the stream produced by the RGB camera of the Kinect (using SDK version 1.8) into an OpenCV (2.4.10) Mat_<Vec3b>. This is my current algorithm, which is not at all fast:
Mat_<Vec3b> mat = Mat::zeros(480, 640, CV_8UC3);
NUI_IMAGE_FRAME imageFrame;
NUI_LOCKED_RECT lockedRect;
if (sensor->NuiImageStreamGetNextFrame(colorStream, 0, &imageFrame) < 0) { return; }
INuiFrameTexture* texture = imageFrame.pFrameTexture;
texture->LockRect(0, &lockedRect, NULL, 0);
if (lockedRect.Pitch != 0)
{
BYTE* upperLeftCorner = (BYTE*)lockedRect.pBits;
BYTE* pointerToTheByteBeingRead = upperLeftCorner;
for (int i = 0; i < 480; i++)
{
for (int j = 0; j < 640; j++)
{
unsigned char r = *pointerToTheByteBeingRead;
pointerToTheByteBeingRead += 1;
unsigned char g = *pointerToTheByteBeingRead;
pointerToTheByteBeingRead += 1;
unsigned char b = *pointerToTheByteBeingRead;
pointerToTheByteBeingRead += 2; //So to skip the alpha channel
mat.at<Vec3b>(Point(j, i))[0] = r;
mat.at<Vec3b>(Point(j, i))[1] = g;
mat.at<Vec3b>(Point(j, i))[2] = b;
}
}
}
texture->UnlockRect(0);
sensor->NuiImageStreamReleaseFrame(colorStream, &imageFrame);
I checked the OpenCV documentation and I understand I'm supposed to use pointer access to increase efficiency. Are Mat_<Vec3b>s stored into memory the same way as Mats or should I do some other pointer arithmetic?
Also, I understand updating every single pixel every time is not the most efficient way of achieving the display of the stream through a Mat. What other things could I do?
Finally figured out how to use pointer arithmetic. The code is self-explanatory:
Mat_<Vec3b> mat = Mat::zeros(480, 640, CV_8UC3);
NUI_IMAGE_FRAME imageFrame;
NUI_LOCKED_RECT lockedRect;
if (sensor->NuiImageStreamGetNextFrame(colorStream, 0, &imageFrame) < 0) { return; }
INuiFrameTexture* texture = imageFrame.pFrameTexture;
texture->LockRect(0, &lockedRect, NULL, 0);
if (lockedRect.Pitch != 0)
{
BYTE* upperLeftCorner = (BYTE*)lockedRect.pBits;
BYTE* pointerToTheByteBeingRead = upperLeftCorner;
for (int i = 0; i < 480; i++)
{
Vec3b *pointerToRow = mat.ptr<Vec3b>(i);
for (int j = 0; j < 640; j++)
{
unsigned char r = *pointerToTheByteBeingRead;
pointerToTheByteBeingRead += 1;
unsigned char g = *pointerToTheByteBeingRead;
pointerToTheByteBeingRead += 1;
unsigned char b = *pointerToTheByteBeingRead;
pointerToTheByteBeingRead += 2; //So to skip the alpha channel
pointerToRow[j] = Vec3b(r, g, b);
}
}
}
texture->UnlockRect(0);
sensor->NuiImageStreamReleaseFrame(colorStream, &imageFrame);