Ask Your Question
0

VideoWriter depthMap

asked 2016-04-09 11:15:24 -0600

cocs78 gravatar image

updated 2016-04-09 11:16:17 -0600

Hi

Is there a way to record 16U Mat with videoWriter to an avi file ?

After recording, I read my video and the result is CV_8UC3 Mat.

For exemple, I get one pixel before record my Mat and i get this same pixel after recording.

Before : CV_16U, value : 2553

After : CV_8UC3, value 11 11 9

Thx

edit retag flag offensive close merge delete

Comments

You can make an RGB image and use ony two channels. After you must use a codec without compression. Of course you can watch your video with vlc but results will be very strange (red channel most signicant bit and blue channel less significant bits...!!)

LBerger gravatar imageLBerger ( 2016-04-09 14:07:38 -0600 )edit

Ok so it's one way to process but it can't be done directly. I'll try thx

cocs78 gravatar imagecocs78 ( 2016-04-09 16:06:37 -0600 )edit
LBerger gravatar imageLBerger ( 2016-04-10 03:22:47 -0600 )edit

I converted my 16Bits Mat to an 8CU3 with :

depthMap(x,y) =( 8UC3(x,y)[0] = depthMap(x,y)/256 , 8UC3(x,y)[1] = depthMap(x,y)%256, 8UC3(x,y)[2] = 0)

By this way I'm able to compute my depth with : depth(x,y) = 8UC3(x,y)[1] * 256 + 8UC3(x,y)[1]

It seems to work :)

I'm not interested to watch my video, it's only a way to save my depthMap faster than using imwrite()

cocs78 gravatar imagecocs78 ( 2016-04-10 04:13:55 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-04-10 10:46:40 -0600

LBerger gravatar image

updated 2016-04-10 10:48:34 -0600

you can try using pointer, opencv function or parallel_loop_body. Best method (relative to speed) will depend of your configuration (image type 16SC or 16UC and image size and your computer) :

class Parallel16BisTo2X8Bits: public ParallelLoopBody
{
private:

Mat &x;
Mat &result;
bool verbose;

public:

Parallel16BisTo2X8Bits(Mat& src, Mat &dst):
    x(src),
    result(dst),
    verbose(false)
{}
void Verbose(bool b){verbose=b;}
virtual void operator()(const Range& range) const
{

    if (verbose)
        cout << getThreadNum()<<"# :Start from row " << range.start << " to "  << range.end-1<<" ("<<range.end-range.start<<" loops)" << endl;

    if (x.type()==CV_16SC1)
        for (int i = range.start; i <  range.end; i++)
        {
            short *pts = (short*)x.ptr(i);
            uchar *ptc = result.ptr(i);
            for (int j=0;j<x.cols;j++,pts++)
            {
                *ptc++= *pts/256;
                *ptc++ = (*pts &0xFF);
                *ptc++=0;
            }

        }
    else
        for (int i = range.start; i <  range.end; i++)
        {
            ushort *pts = (ushort*)x.ptr(i);
            uchar *ptc = result.ptr(i);
            for (int j=0;j<x.cols;j++,pts++)
            {
                *ptc++= *pts/256;
                *ptc++ = (*pts &0xFF);
                *ptc++=0;
            }

        }

}
Parallel16BisTo2X8Bits& operator=(const Parallel16BisTo2X8Bits &) {
     return *this;
};
};

int main(int argc, char* argv[])
{

int type=CV_16SC1;
Mat x(1000,1023,type);
for (int i=0;i<x.rows;i++)
    for (int j=0;j<x.cols;j++)
        x.at<short>(i,j)=rand()%32767;

vector<Mat> m(3);
m[2] = Mat::zeros (x.rows,x.cols,CV_8UC1);
Mat lsb=Mat::zeros (x.rows,x.cols,type),msb=Mat::zeros (x.rows,x.cols,type),result=Mat::zeros(x.rows,x.cols,CV_8UC3);
// That's only for fun : compile ocl function speed time is equal to compiletime
int64 tpsIni = getTickCount();

bitwise_and(x,0xFF,lsb);
lsb.convertTo(m[1],CV_8UC1,1);
x.convertTo(m[0],CV_8UC1,1./256);

merge(m,result);
int64 tpsFin = getTickCount();
// Time using pointer 
result=Mat::zeros(x.rows,x.cols,CV_8UC3);
tpsIni = getTickCount();
if (type==CV_16UC1)
    for (int i = 0; i < x.rows; i++)
        {
            ushort *pts = (ushort*)x.ptr(i);
            uchar *ptc = (uchar*)result.ptr(i);
            for (int j=0;j<x.cols;j++,pts++,ptc++)
            {
                *ptc++= *pts/256;
                *ptc++ = (*pts &0xFF);
            }

        }
else
    for (int i = 0; i < x.rows; i++)
    {
        short *pts = (short*)x.ptr(i);
        uchar *ptc = (uchar*)result.ptr(i);
        for (int j=0;j<x.cols;j++,pts++,ptc++)
        {
            *ptc++= *pts/256;
            *ptc++ = (*pts &0xFF);
        }

    }
tpsFin = getTickCount();
cout << result.at<Vec3b>(64,32)<<endl;
cout << "Time pointer ="<<tpsFin-tpsIni<<"\n";
imshow("color(pointer)",result);
// Time using opencv fucntion with opencl
tpsIni = getTickCount();

{
bitwise_and(x,0xFF,lsb);
lsb.convertTo(m[1],CV_8UC1);
x.convertTo(m[0],CV_8UC1,1./256);

merge(m,result);

}
tpsFin = getTickCount();
imshow("color(ocv)",result);
cout << result.at<Vec3b>(64,32)<<endl;
cout << "Time opencv function with ocl ="<<tpsFin-tpsIni<<"\n";


Parallel16BisTo2X8Bits p(x,result);
cout << getNumThreads()<<endl;
tpsIni = getTickCount();
parallel_for_(Range(0,x.rows), p,4);
tpsFin = getTickCount();
imshow("color(parallel)",result);
cout << result.at<Vec3b>(64,32)<<endl;
cout << "Time opencv function with parallel ="<<tpsFin-tpsIni<<"\n";


waitKey();
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-04-09 11:15:24 -0600

Seen: 479 times

Last updated: Apr 10 '16