<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>More Than Technical</title>
	
	<link>http://www.morethantechnical.com</link>
	<description>On software, code, the internet and more.</description>
	<lastBuildDate>Sat, 06 Mar 2010 16:53:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/MoreThanTechnical" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="morethantechnical" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Implementing PTAM: stereo, tracking and pose estimation for AR with OpenCV [w/ code]</title>
		<link>http://www.morethantechnical.com/2010/03/06/implementing-ptam-stereo-tracking-and-pose-estimation-for-ar-with-opencv-w-code/</link>
		<comments>http://www.morethantechnical.com/2010/03/06/implementing-ptam-stereo-tracking-and-pose-estimation-for-ar-with-opencv-w-code/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 16:53:11 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[school]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[vision]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[augmented reality]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=606</guid>
		<description><![CDATA[Hi
Been working hard at a project for school the past month, implementing one of the more interesting works I&#8217;ve seen in the AR arena: Parallel Tracking and Mapping (PTAM) [PDF]. This is a work by George Klein [homepage] and David Murray from Oxford university, presented in ISMAR 2007.
When I first saw it on youtube [link] [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.morethantechnical.com/wp-content/uploads/2010/03/ptam.png" rel="lightbox[606]"><img src="http://www.morethantechnical.com/wp-content/uploads/2010/03/ptam.png" alt="" title="ptam" width="350" height="286" class="alignleft size-full wp-image-617" /></a>Hi</p>
<p>Been working hard at a project for school the past month, implementing one of the more interesting works I&#8217;ve seen in the AR arena: Parallel Tracking and Mapping (PTAM) [<a href="http://www.robots.ox.ac.uk/~gk/publications/KleinMurray2007ISMAR.pdf" target="_blank">PDF</a>]. This is a work by George Klein [<a href="http://www.robots.ox.ac.uk/~gk/" target="_blank">homepage</a>] and David Murray from Oxford university, presented in ISMAR 2007.</p>
<p>When I first saw it on youtube [<a href="http://www.youtube.com/watch?v=pBI5HwitBX4" target="_blank">link</a>] I immediately saw the immense potential &#8211; mobile markerless augmented reality. I thought I should get to know this work a bit more closely, so I chose to implement it as a part of advanced computer vision course, given by Dr. Lior Wolf [<a href="http://www.cs.tau.ac.il/~wolf/" target="_blank">link</a>] at TAU.</p>
<p>The work is very extensive, and clearly is a result of deep research in the field, so I set to achieve a few selected features: Stereo initialization, Tracking, and small map upkeeping. I chose not to implement relocalization and full map handling.</p>
<p>This post is kind of a tutorial for 3D reconstruction with OpenCV 2.0. I will show practical use of the functions in cvtriangulation.cpp, which are not documented and in fact incomplete. Furthermore I&#8217;ll show how to easily combine OpenCV and OpenGL for 3D augmentations, a thing which is only briefly described in the docs or online.</p>
<p>Here are the step I took and things I learned in the process of implementing the work.<br />
<span id="more-606"></span></p>
<h2>Preparations&#8230;</h2>
<p>Before going straight to coding, I had to prepare a few things.</p>
<ul>
<li>A working compilation of OpenCV &#8211; not trivial with the new version 2.0.</li>
<li>A calibrated camera.</li>
<li>Test data</li>
</ul>
<p>Compiling OpenCV 2.0 proved to be a bit tricky. Even though the sourceforge project offers binary release for Win32, I compiled the whole thing from source. It turned out the binary release doesn&#8217;t contain .lib files, and anyway has compatibility issues between MS VS 2005 and 2008 &#8211; something about the embedded manifest [<a href="http://www.google.com/search?q=opencv+2.0+VS+2008+manifest+erro" target="_blank">google</a>]. I downloaded the freshest source from SVN, and compiled it, but it didn&#8217;t solve the debug-release problem, so I was left with using the release dlls even for debug evironment.</p>
<p>Initially I thought I&#8217;ll try an uncalibrated camera approach, but soon abandoned it. I had to calibrate my cameras, which I did  very easily using OpenCV&#8217;s &#8220;calibration.cpp&#8221;, which strangely is <strong>not built</strong> when building all examples &#8211; it has to be built manually. But everything went smoothly, and I soon got a calibration matrix (focal length, center of projection) and radial distortion coefficients.</p>
<h3>Getting Test Data</h3>
<p><object style="width: 480px; height: 295px;" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="295" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.youtube.com/v/WXsufPbEUmM&amp;hl=en_US&amp;fs=1&amp;" /><param name="align" value="left" /><embed style="width: 480px; height: 295px;" type="application/x-shockwave-flash" width="480" height="295" src="http://www.youtube.com/v/WXsufPbEUmM&amp;hl=en_US&amp;fs=1&amp;" align="left"></embed></object>For the test data I wanted to get a few views of a planar scene, where the first two views are separated only by a translation of ~5cm, as K&amp;M do in the PTAM article. This known translation is helpful when trying to triangulate the initial features in the scene. When you have prior knowledge of where the cameras are, you can simply intersect the epipolar lines between the two views and recover the 3D position of the points &#8211; up to a scale. Keep in mind you must also have feature correspondence: a point on image A must be correlated to a point in image B.</p>
<p>To achieve this I set up a small program that uses Optical Flow to track some 2D features in the scene, and grab a few screens + feature vectors. See &#8216;capture_data.cpp&#8217;.</p>
<h2>Stereo Initialization</h2>
<p>Now that I have 2 views with feature correspodence:</p>
<p><a rel="lightbox" href="http://www.morethantechnical.com/wp-content/uploads/2010/03/frames_correl.png"><img class="alignnone size-full wp-image-607" title="frames_correl" src="http://www.morethantechnical.com/wp-content/uploads/2010/03/frames_correl.png" alt="" width="634" height="259" /></a></p>
<p>I would like to triangulate the features. This is possible, as I discussed earlier, since I know the rotation (none), translation (5cm on -x axis) and camera calibration parameters (focal length, center of projection).</p>
<h3>Triangulation</h3>
<p>For triangulation, OpenCV has only recently added a couple of functions that implement triangulation [<a href="http://n2.nabble.com/An-implementation-of-the-Optimal-Triangulation-Method-td2295331.html" target="_blank">link</a>] as shown by Hartly &amp; Zisserman [<a href="http://users.cecs.anu.edu.au/~hartley/Papers/CVPR99-tutorial/tut_4up.pdf" target="_blank">PDF</a>, page 12]. However, these functions are not formally documented, and in fact they are missing some important parts. This is how I used cvTriangulation(), which is the key function:</p>
<pre class="brush: plain;">
//this function will initialize the 3D features from two views
void stereoInit() {

//first load camera intrinsic parameters
FileStorage fs(&quot;cam_work.out&quot;,CV_STORAGE_READ);
FileNode fn = fs[&quot;camera_matrix&quot;];
camera_matrix = Mat((CvMat*)fn.readObj(),true);

fn = fs[&quot;distortion_coefficients&quot;];
distortion_coefficients = Mat((CvMat*)fn.readObj(),true);

//vector&lt;Point2d&gt; points[2]; //these Point2d vectors hold the 2D features, double precision, from the 2 views

//get copy of points
_points[0] = points[0];
_points[1] = points[1];
Mat pts1M(_points[0]), pts2M(_points[1]); //very easy in OpenCV 2.0 to convert vector&lt;&gt; to Mat.

//Undistort points
Mat tmp,tmpOut;
pts1M.convertTo(tmp,CV_32FC2);  //undistort takes only floats not doubles, so convert to Point2f
undistortPoints(tmp,tmpOut,camera_matrix,distortion_coefficients);
tmpOut.convertTo(pts1M,CV_64FC2);  //go back to double precision

pts2M.convertTo(tmp,CV_32FC2);
undistortPoints(tmp,tmpOut,camera_matrix,distortion_coefficients);
tmpOut.convertTo(pts2M,CV_64FC2);

vector&lt;uchar&gt; tri_status; //this will hold the status for each point, a good point will have 1, bad - 0

//now triangulate
triangulate(_points[0],_points[1],tri_status);

}

void triangulate(vector&lt;Point2d&gt;&amp; points1, vector&lt;Point2d&gt;&amp; points2, vector&lt;uchar&gt;&amp; status) {

	//Convert points to 1-channel, 2-rows, double precision - This is important - see the code
...

	Mat ___tmp(2,pts1Mt.cols,CV_64FC1,__d);
...
	Mat ___tmp1(2,pts2Mt.cols,CV_64FC1,__d1);
...

	CvMat __points1 = ___tmp, __points2 = ___tmp1;

	//projection matrices
	double P1d[12] = {	-1,0,0,0,
						0,1,0,0,
						0,0,1,0 };	//Identity, but looking into -z axis
	Mat P1m(3,4,CV_64FC1,P1d);
	CvMat* P1 = &amp;(CvMat)P1m;
	double P2d[12] = {	-1,0,0,-5,
						0,1,0,0,
						0,0,1,0 };  //Identity rotation, 5cm -x translation, looking into -z axis
	Mat P2m(3,4,CV_64FC1,P2d);
	CvMat* P2 = &amp;(CvMat)P2m;

	float _d[1000] = {0.0f};
	Mat outTM(4,points1.size(),CV_32FC1,_d);
	CvMat* out = &amp;(CvMat)outTM;

//using cvTriangulate with the created structures
	cvTriangulatePoints(P1,P2,&amp;__points1,&amp;__points2,out);

//we should check the triangulation result by reprojecting 3D-&gt;2D and checking distance
	vector&lt;Point2d&gt; projPoints[2] = {points1,points2};

	double point2D_dat[3] = {0};
	double point3D_dat[4] = {0};
	Mat twoD(3,1,CV_64FC1,point2D_dat);
	Mat threeD(4,1,CV_64FC1,point3D_dat);

	Mat P[2] = {Mat(P1),Mat(P2)};

	int oc = out-&gt;cols, oc2 = out-&gt;cols*2, oc3 = out-&gt;cols*3;

	status = vector&lt;uchar&gt;(oc);

	//scan all points, reproject 3D-&gt;2D, and keep only good ones
	for(int i=0;i&lt;oc;i++) {
		double W = out-&gt;data.fl[i+oc3];
        point3D_dat[0] = out-&gt;data.fl[i] / W;
        point3D_dat[1] = out-&gt;data.fl[i+oc] / W;
        point3D_dat[2] = out-&gt;data.fl[i+oc2] / W;
        point3D_dat[3] = 1;

        bool push = true;
        /* !!! Project this point for each camera */
        for( int currCamera = 0; currCamera &lt; 2; currCamera++ )
        {
            //reproject! using the P matrix of the current camera
			twoD = P[currCamera] * threeD;

            float x,y;
            float xr,yr,wr;
 	x = (float)projPoints[currCamera][i].x;
	y = (float)projPoints[currCamera][i].y;

            wr = (float)point2D_dat[2];
            xr = (float)(point2D_dat[0]/wr);
            yr = (float)(point2D_dat[1]/wr);

            float deltaX,deltaY;
            deltaX = (float)fabs(x-xr);
            deltaY = (float)fabs(y-yr);

			//printf(&quot;error from cam %d (%.2f,%.2f): %.6f %.6f\n&quot;,currCamera,x,y,deltaX,deltaY);

			if(deltaX &gt; 0.01 || deltaY &gt; 0.01) {
				push = false;
			}
        }
		if(push) {
			// A good 3D reconstructed point, add to known world points

			double s = 7;
			Point3d p3d(point3D_dat[0]/s,point3D_dat[1]/s,point3D_dat[2]/s);
			//printf(&quot;%.3f %.3f %.3f\n&quot;,p3d.x,p3d.y,p3d.z);
			points1Proj.push_back(p3d);
			status[i] = 1;
		} else {
			status[i] = 0;
		}

	}
}
</pre>
<p>OK, now that I have (hopefully) triangulated 3D features from the initial state: 2 views of a planar scene with 5cm translation on the X axis &#8211; I can move on the pose estimation.</p>
<h2>Pose Estimation</h2>
<p>Theoretically, if I know the 3D position of features in the world and their respective 2D position in the image, it should be easy to recover the position of the camera, because there are a rotation matrix and translation vector that define this transformation. Practically in OpenCV, finding the position of an object using 3D-2D correlation is done by using the solvePnP() [<a href="http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html#solvepnp" target="_blank">link</a>] function.</p>
<p>Since I have an initial guess of the rotation and translation &#8211; from the first 2 frames &#8211; I can &#8220;help&#8221; the function estimate the new ones.</p>
<pre class="brush: plain;">
void findExtrinsics(vector&lt;Point2d&gt;&amp; points, vector&lt;double&gt;&amp; rv, vector&lt;double&gt;&amp; tv) {
	//estimate extrinsics for these points

	Mat rvec(rv),tvec(tv);

//initial &quot;guess&quot;, in case it wasn't already supplied
	if(rv.size()!=3) {
		rv = vector&lt;double&gt;(3);
		rvec = Mat(rv);
		double _d[9] = {1,0,0,
						0,-1,0,
						0,0,-1};
		Rodrigues(Mat(3,3,CV_64FC1,_d),rvec);
	}
	if(tv.size()!=3) {
		tv = vector&lt;double&gt;(3);
		tv[0]=0;tv[1]=0;tv[2]=0;
		tvec = Mat(tv);
	}

	//create a float rep  of points
	vector&lt;Point2f&gt; v2(points.size());
	Mat tmpOut(v2);
	Mat _tmpOut(points);
	_tmpOut.convertTo(tmpOut,CV_32FC2);

	solvePnP(points1projMF,tmpOut,camera_matrix,distortion_coefficients,rvec,tvec,true);

	printf(&quot;frame extrinsic:\nrvec: %.3f %.3f %.3f\ntvec: %.3f %.3f %.3f\n&quot;,rv[0],rv[1],rv[2],tv[0],tv[1],tv[2]);

//the output of the function is a Rodrigues form of rotation, so convert to regular rot-matrix
	Mat rotM(3,3,CV_64FC1); ///,_r);
	Rodrigues(rvec,rotM);
	double* _r = rotM.ptr&lt;double&gt;();
	printf(&quot;rotation mat: \n %.3f %.3f %.3f\n%.3f %.3f %.3f\n%.3f %.3f %.3f\n&quot;,
		_r[0],_r[1],_r[2],_r[3],_r[4],_r[5],_r[6],_r[7],_r[8]);
}
</pre>
<p>After getting the extrinsic parameters of the camera, the next step is plugging in the visualization!</p>
<h2>Integrating OpenGL</h2>
<p>Generally, it should be possible to create a 3D scene that matches exactly the true world scene, where the triangulated features appear in the scene aligned exactly with the world. I was not able to achieve that, but I got pretty close:<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/Q1HVjAWls_E&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/Q1HVjAWls_E&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>It&#8217;s basically what you do in augmented reality, you align the virtual camera&#8217;s position and rotation with the results you get from the vision part of the system. In the pose estimation we ended with a 3D rotation vector (Rodrigues form) and 3D translation vector which is used as-is, so only the rotation vector should be converted to 3&#215;3 matrix using the Rodrigues() function.</p>
<p>This is the OpenGL glut display() function that draws the scene:</p>
<pre class="brush: plain;">
void display(void)
{
	glClearColor(1.0f, 1.0f, 1.0f, 0.5f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer

	//draw the background - the frame from the camers
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	gluOrtho2D(0.0,352.0,288.0,0.0);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glDisable(GL_DEPTH_TEST);
	glDrawPixels(352,288,GL_RGB,GL_UNSIGNED_BYTE,backPxls.data);
	glEnable(GL_DEPTH_TEST);
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

    const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
	a = t*20.0;

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

//use the camera position 3D vector
	curCam[0] = cam[0]; curCam[1] = cam[1]; curCam[2] = cam[2];
//there seems to be some kind of offset...
	glTranslated(-curCam[0]+0.5,-curCam[1]+0.7,-curCam[2]);

//and the 3x3 rotation matrix
	double _d[16] = {	rot[0],rot[1],rot[2],0,
						rot[3],rot[4],rot[5],0,
						rot[6],rot[7],rot[8],0,
						0,	   0,	  0		,1};
	glMultMatrixd(_d);

//flip the rotation on the x-axis
	glRotated(180,1,0,0);

	//draw the 3D feature points
	glPushMatrix();
	glColor4d(1.0,0.0,0.0,1.0);
	for(unsigned int i=0;i&lt;points1Proj.size();i++) {
		glPushMatrix();
glTranslated(points1Proj[i].x,points1Proj[i].y,points1Proj[i].z);
		glutSolidSphere(0.03,15,15);
		glPopMatrix();
	}
	glPopMatrix();

	glutSwapBuffers();

	if(!running) {
		glutLeaveMainLoop();
	}

	Sleep(25);
}
</pre>
<p>This pretty much coveres my work, in a very concise way. The complete source code will reveal all I have done, and will provide a better copy-and-paste ground for your own projects.</p>
<h2>Things not covered in this work</h2>
<p>Initially I tried to implement a very crucial part of the PTAM work &#8211; pairing the 3D map with 2D features in the image. This allows them to re-align the map in every frame (when the tracking is bad) so the pose estimation does not &#8220;loose grip&#8221;. In essence, they keep a visual identity for each map feature, very similar to a descriptor like SURF or SIFT, so at any point they can find where in the new image are the features and recover the camera pose from the 2D-3D correspondence. I ran into a problem utilizing OpenCV&#8217;s SURF functionality, it seems to have a bug when trying to compute the descriptor for user-given feature points.</p>
<p>Another thing I chose not to implement is creating a full map of the surroundings. I wanted to achieve a simple working solution for a small map (essentially a single frame), and see how it works. In the original work by K&amp;M they constantly add more and more features to the map untill it has covered the whole surrounding room.</p>
<h2>Code</h2>
<p>As usual my code is available for checkout from the blog&#8217;s SNV repo:</p>
<pre class="brush: plain;">
svn checkout http://morethantechnical.googlecode.com/svn/trunk/ptam ptam
</pre>
<p>Thanks Lior for your help getting the hang of these subjects, and the opportunity to meddle with a subject I long gone wanted to explore.</p>
<p>I hope everyone will enjoy and learn from my enjoyment and learning.</p>
<p>Bye!</p>
<p>Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F03%2F06%2Fimplementing-ptam-stereo-tracking-and-pose-estimation-for-ar-with-opencv-w-code%2F&amp;linkname=Implementing%20PTAM%3A%20stereo%2C%20tracking%20and%20pose%20estimation%20for%20AR%20with%20OpenCV%20%5Bw%2F%20code%5D"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/03/06/implementing-ptam-stereo-tracking-and-pose-estimation-for-ar-with-opencv-w-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone OS 3.x Raw data of camera frames</title>
		<link>http://www.morethantechnical.com/2010/02/27/iphone-os-3-x-raw-data-of-camera-frames/</link>
		<comments>http://www.morethantechnical.com/2010/02/27/iphone-os-3-x-raw-data-of-camera-frames/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 20:44:32 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Mobile phones]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[vision]]></category>
		<category><![CDATA[frame grabbing]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=599</guid>
		<description><![CDATA[Hi All
It looks like it&#8217;s finally here &#8211; a way to grab the raw data of the camera frames on the iPhone OS 3.x. 
A gifted hacker named John DeWeese was nice enough to comment on a post from May 09&#8242; with his method of hacking the APIs to get the frames. Though cumbersome, it [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.morethantechnical.com/wp-content/uploads/2010/02/iphone-os-3-STEWIE.png" rel="lightbox[599]"><img src="http://www.morethantechnical.com/wp-content/uploads/2010/02/iphone-os-3-STEWIE-300x212.png" alt="" title="&quot;where is my data?!&quot;" width="300" height="212" class="alignleft size-medium wp-image-601" /></a>Hi All</p>
<p>It looks like it&#8217;s finally here &#8211; a way to grab the raw data of the camera frames on the iPhone OS 3.x. </p>
<p>A gifted hacker named <a href="http://deweeeese.blogspot.com/">John DeWeese</a> was nice enough to comment on <a href="http://www.morethantechnical.com/2009/05/06/iphone-camera-frame-grabbing-and-a-real-time-meanshift-tracker/">a post from May 09&#8242;</a> with <a href="http://deweeeese.blogspot.com/2010/02/processing-iphone-camera-video-on.html">his method of hacking the APIs to get the frames</a>. Though cumbersome, it looks like it should work, but I haven&#8217;t tried it yet. I promise to try it soon and share my results.</p>
<p>Way to go John!<br />
Some code would be awesome&#8230;</p>
<p>Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F02%2F27%2Fiphone-os-3-x-raw-data-of-camera-frames%2F&amp;linkname=iPhone%20OS%203.x%20Raw%20data%20of%20camera%20frames"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/02/27/iphone-os-3-x-raw-data-of-camera-frames/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SmartHome – Embedded computing course project</title>
		<link>http://www.morethantechnical.com/2010/02/21/smarthome-embedded-computing-course-project/</link>
		<comments>http://www.morethantechnical.com/2010/02/21/smarthome-embedded-computing-course-project/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 16:42:09 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[school]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[swt]]></category>
		<category><![CDATA[zigbee]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=580</guid>
		<description><![CDATA[Hi
In the past few weeks I have been working hard at a few projects for end-of-term at Uni. One of the projects is what I called &#8220;SmartHome&#8221;, for Embedded computing [link] course, is a home monitoring [link] application. In the course the students were given an LPC2148 arm7-MCU (NXP) based education board, implemented by Embedded [...]]]></description>
			<content:encoded><![CDATA[<p>Hi<br />
In the past few weeks I have been working hard at a few projects for end-of-term at Uni. One of the projects is what I called &#8220;SmartHome&#8221;, for Embedded computing [<a href="http://www.tau.ac.il/~stoledo/Courses/Embedded/announcement.html" target="_blank">link</a>] course, is a home monitoring [<a href="http://en.wikipedia.org/wiki/Home_automation" target="_blank">link</a>] application. In the course the students were given an LPC2148 arm7-MCU (NXP) based education board, implemented by Embedded Artists [<a href="http://www.embeddedartists.com/products/education/edu_2148.php" target="_blank">link</a>]. My partner Gil and I decided to work with ZigBee extension modules [<a href="http://en.wikipedia.org/wiki/ZigBee" target="_blank">link</a>] to enable remote communication.</p>
<p>Here are the steps we took to bring this project to life.<br />
<span id="more-580"></span></p>
<h2>The Idea</h2>
<p>Our vision is to create a home monitoring and controlling system, that will enable tracking different sensors around the house and also control switches.The system should be centralized by a master controller, and also wireless so it will not need cumbersome wiring throughout the house. We would also like the system to be easily controlled by a PC, so visual information could be displayed to the user, as well as allow manual control of the electronic switches.</p>
<p>Such a system will be able to automatically:</p>
<ul>
<li>Turn off the garden lighting when the light outside is bright enough,</li>
<li>Control the lawn watering system,</li>
<li>Control air conditioning in the house according to the temperature,</li>
<li>etc.</li>
</ul>
<h2>The Hardware</h2>
<p style="text-align: left;">As I mentioned, we were given an LPC2148 education board [<a href="http://www.embeddedartists.com/products/education/edu_2148.php" target="_blank">link</a>], implemented by Embedded Artists, that boasts a 12Mhz ARM CPU, and many peripheral subsystems. Among the systems are: LCD screen, numerous LEDs, a LED matrix, a fan, analog dials, USB and UART I/O and more. The boards also has a port for connecting a ZigBee module to enable RF communication, but it doesn&#8217;t contain the actual module. Since we needed remote communication between our stations, we bought 3 XBee modules from Maxstream [<a href="http://www.digi.com/products/wireless/point-multipoint/xbee-series1-module.jsp#overview" target="_blank">link</a>].</p>
<p style="text-align: center;"><a href="http://www.morethantechnical.com/wp-content/uploads/2010/02/Image096.jpg" rel="lightbox[580]"><img class="size-medium wp-image-586 alignnone" title="XBee module by MaxStream" src="http://www.morethantechnical.com/wp-content/uploads/2010/02/Image096-300x225.jpg" alt="" width="210" height="158" /></a><a href="http://www.morethantechnical.com/wp-content/uploads/2010/02/Image097.jpg" rel="lightbox[580]"> <img class="size-medium wp-image-588 alignnone" title="LPC2148 board by Embedded Artists" src="http://www.morethantechnical.com/wp-content/uploads/2010/02/Image097-300x225.jpg" alt="" width="210" height="158" /></a><a href="http://www.morethantechnical.com/wp-content/uploads/2010/02/Image098.jpg" rel="lightbox[580]"> <img class="alignnone size-medium wp-image-589" title="XBee module on LPC2148 board" src="http://www.morethantechnical.com/wp-content/uploads/2010/02/Image098-300x225.jpg" alt="" width="210" height="158" /></a></p>
<h2>The Software</h2>
<p>The LPC boards can be programmed very easily using tools provided by Embedded Artists, such as GCC with Newlib for compiling (both Win and Linux), and <a href="http://www.flashmagictool.com/" target="_blank">Flashmagic</a> (for windows) or lpc21isp for loading the compiled program. We used these tools for programing the &#8220;embedded&#8221; part of the application, for the PC client we used Java with <a href="http://www.eclipse.org/swt/" target="_blank">SWT</a> and serial port connectivity (<a href="http://rxtx.qbang.org/wiki/index.php/Download" target="_blank">RxTx</a> for Windows and Linux).</p>
<h3>Embedded program</h3>
<p>The embedded program on the LPC board has two parts: A master and A client. The system has only one master, and up to 3 clients. The master gathers information from the clients, and controls their behavior according to the user requests. For communication between the master and clients we created a communication protocol that has only a few simple messages:</p>
<ul>
<li>INIT &#8211; The master sends this request to initialize the connection between itself and a client.</li>
<li>ACK &#8211; This is the response for every request.</li>
<li>POLL &#8211; The clients answers this request with the data from all it&#8217;s sensors.</li>
<li>OPERATE &#8211; The master commands the client to switch something on or off.</li>
<li>ERROR &#8211; A general error response.</li>
</ul>
<p>All commands / responses have a unified structure described here:</p>
<pre class="brush: plain;">
General struct:
 ___________________________________________ _____
|    OP   | To | From | &lt;----- DATA ------&gt; | EOM
|_________|____|______|_____________________|_____

Data:

POLL (response)
_ ____________ ______ ______ ________
 | Temperature| ADC0 | ADC1 | Button |
_|____________|______|______|________|

OPERATE
_ _________
 | BITMASK |
_|_________|
</pre>
<p>This way we had a very easy implementation of the communication module, since we always had to look for only 14 bytes on the wire.</p>
<h3>Communication with ZigBee module</h3>
<p>To jumpstart our implementation we used the examples provided by Embedded Artists for operating the ZigBee module [<a href="http://www.embeddedartists.com/support/LPC2148_EDU/XBee_example.zip" target="_blank">link</a>]. The communication with the ZigBee module is on the UART1 port of the MCU. The example code takes care of opening the correct GPIO pins, setting the IRQ masks to enable interrupts and provides a very simple API for transmitting and receiving characters with the XBee over UART  (described in uart.h and uart.c files).</p>
<p>We took the XBee example code and expanded it to be able to recieve and send data between two stations. That means setting up each station&#8217;s module with it&#8217;s ID, address, channel and target address by AT commands [<a href="http://ftp1.digi.com/support/documentation/90000982_B.pdf" target="_blank">spec</a>, see page. 28]: ATID, ATCH, ATMY and ATDL. Two other key features are putting the module into command mode (rather than transmit mode) to set the mentioned parameters, this is done by &#8216;+++&#8217; to enter command mode and ATCN to exit. Once we had a decent framework to communicate between the stations, we started to build the logic.</p>
<p>The master station logic is like so:</p>
<ol>
<li>Initialize XBee module.</li>
<li>INIT all client stations, and see which station answers &#8211; these will be our &#8220;up&#8221; stations.</li>
<li>Loop:
<ol>
<li>POLL each &#8220;up&#8221; station in a loop.</li>
<li>Take care of any OPERATE requests from the PC client.</li>
</ol>
</li>
</ol>
<p>This way, the client&#8217;s logic boils down to just looping, testing for any request and taking care of it. Both client and master share most of the code, so only the main process code is essentially different. The example code uses a framework called &#8220;Preemtive OS&#8221; to allow multitasking / processes (code was bundled in the examples).</p>
<h3>Communication with PC</h3>
<p>Communication between the master and PC client also required some lightweight &#8220;protocol&#8221;. The communication is again over UART (0 this time, 1 is used by XBee), only now the PC is doing a UART-over-USB with the board. The protocol we ended up with supports these features:</p>
<ul>
<li>Commands the PC wants the master to perform look like &#8220;m=&lt;command&gt;=&lt;parameters&gt;&#8221;, such commands can be:
<ul>
<li>&#8220;poll=&lt;i&gt;&#8221;, send a POLL to the station indexed i</li>
<li>&#8220;test=&lt;i&gt;&#8221;, send an INIT to the station indexed i</li>
<li>&#8220;toggle=&lt;i&gt;_&lt;sw&gt;_&lt;onoff&gt;&#8221;, set the switch <em>sw</em> on the station indexed <em>i</em> to <em>onoff</em> status</li>
</ul>
</li>
<li>Notifications the master would like to share with the user (PC) look like &#8220;pc=&lt;notification&gt;&#8221;, such notifications can be:
<ul>
<li> &#8220;up=&lt;i&gt;&#8221;, the station indexed <em>i</em> is up</li>
<li>&#8220;master_online&#8221;,</li>
<li>&#8220;temp=&lt;i&gt; &lt;temp&gt;&#8221;, the station indexed <em>i</em> has a temperature reading of <em>temp</em></li>
<li>&#8220;e=&lt;error message&gt;&#8221;, error message from the master</li>
</ul>
</li>
</ul>
<p>This is an incomplete set of features, but it&#8217;s representative of the idea we want to present.</p>
<h3>PC client program</h3>
<p>The PC client we built using Java, so it would (and should) be portable between OSs. The GUI was built with the SWT, using the eclipse Visual Editor plug-in which simplified the process. Communication with the LPC board is done over the serial port of the board, as I mentioned the PC creates a virtual COM port using a USB-to-UART driver (FTDI, bundled with windows) [<a href="http://en.wikipedia.org/wiki/FTDI" target="_blank">link</a>].</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/1ZC2SuYb7P0&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/1ZC2SuYb7P0&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>To test the GUI we created a &#8220;simulator&#8221;, that mimics the operation of a master station, that is shown in the video above.</p>
<p>The high-level design of the program is described in this inheritance UML diagram:</p>
<p style="text-align: center;"><a href="http://www.morethantechnical.com/wp-content/uploads/2010/02/smart_home_uml.png" rel="lightbox[580]"><img class="size-medium wp-image-593 aligncenter" title="smart_home_uml" src="http://www.morethantechnical.com/wp-content/uploads/2010/02/smart_home_uml-251x300.png" alt="" width="251" height="300" /></a></p>
<p>Our PC client uses serial-port connectivity based on the old javax.serial APIs. Though these APIs have been abandoned by Sun, and there is no official Win32 implementation bundled with the JDK (only for *NIXs/Solaris), a project named RxTx is upkeeping an implementation of this API for windows [<a href="http://rxtx.qbang.org/wiki/index.php/Download" target="_blank">link</a>].</p>
<h2>The Code</h2>
<p>We are releasing the code under the BSD license, for everyone to use, enjoy, learn and expand.</p>
<p>It is available via the blog&#8217;s SVN repo:</p>
<p>PC Client (requires RxTx serial port impl and SWT)</p>
<pre class="brush: plain;">
svn checkout http://morethantechnical.googlecode.com/svn/trunk/SmartHomePCClient
</pre>
<p>Embedded program (includes all dependencies)</p>
<pre class="brush: plain;">
svn checkout http://morethantechnical.googlecode.com/svn/trunk/smarthome_embedded/final project
</pre>
<p>To compile the master program &#8220;make&#8221; in the master directory, and you&#8217;ll get an &#8220;xbee_master.hex&#8221; file, same goes for the client in the client directory (these directories don&#8217;t contain code, only a makefile). Then you have to upload the hex into the board, this is done either by &#8220;make deploy&#8221; (if you have lpc21isp), or FlashMagic on Win.</p>
<p>Java is compiled as usual&#8230; just remember the dependencies.</p>
<p>We would like to thank Sivan Toledo for the guidance, loaned hardware and inspiration.</p>
<p>And thanks all for listening!<br />
Roy Shilkrot &amp; Gil Ramon</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F02%2F21%2Fsmarthome-embedded-computing-course-project%2F&amp;linkname=SmartHome%20%26%238211%3B%20Embedded%20computing%20course%20project"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/02/21/smarthome-embedded-computing-course-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stream your favorite radio station to your workplace</title>
		<link>http://www.morethantechnical.com/2010/01/29/stream-your-favorite-radio-station-to-your-workplace/</link>
		<comments>http://www.morethantechnical.com/2010/01/29/stream-your-favorite-radio-station-to-your-workplace/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 14:53:00 +0000</pubDate>
		<dc:creator>Arnon</dc:creator>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Stream]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[block]]></category>
		<category><![CDATA[bypass]]></category>
		<category><![CDATA[corporate]]></category>
		<category><![CDATA[re-stream]]></category>
		<category><![CDATA[vlc]]></category>
		<category><![CDATA[worksplace]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=567</guid>
		<description><![CDATA[I want to suggest a trick that worked for me. My work place blocks most of the popular radio stations stream sites in my country.
I can understand why they&#8217;re doing that, but hey – if you want to save bandwidth I suggest you block YouTube (not that I complain…)
Well, I thought of a way to [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">I want to suggest a trick that worked for me. My work place blocks most of the popular radio stations stream sites in my country.<br />
I can understand why they&#8217;re doing that, but hey – if you want to save bandwidth I suggest you block YouTube (not that I complain…)<br />
Well, I thought of a way to listen to my favorite radio station from work, by re-streaming it from my home. And it worked!</p>
<p style="text-align: left;">It can also work for you, in case your IT does not block by protocol, only by address.</p>
<p style="text-align: left;">So here&#8217;s how to do it:</p>
<p style="text-align: left;"><span id="more-567"></span></p>
<h2 style="text-align: left;">STEP 1 – Retrieve the actual link for your radio station</h2>
<p style="text-align: left;">Go to the station&#8217;s website and try to get a link that you can play in Windows Media Center.<br />
Some stations will let you find it, others won&#8217;t.<br />
If this is the case, here&#8217;s what you need to do (At home!)</p>
<ol style="text-align: left;">
<li>
<div style="text-align: justify;">Download <a href="http://www.wireshark.org/">wireshark</a> and install it</div>
</li>
<li>
<div style="text-align: justify;">Start capturing using this filter: <strong>rtsp.request</strong></div>
</li>
<li>
<div style="text-align: justify;">Try to listen to the station</div>
</li>
<li>
<div style="text-align: justify;">You should see such an output in wireshark:</div>
<p style="text-align: right;"><img class="alignleft" src="http://www.morethantechnical.com/wp-content/uploads/2010/01/012910_1452_Streamyourf1.png" alt="" /></p>
<p style="text-align: left;">As you can see, there is a url here that looks like this:<br />
<strong>rtsp://someurl/somefile RTSP/1.0</strong></p>
</li>
<li>Take this URL, and replace <strong>RTSP</strong> with <strong>MMS</strong> and omit the <strong>RTSP/1.0</strong> ending.<br />
Your URL should look like this: <a href="mms://someurl.somefile">mms://someurl.somefile</a></li>
<li>
<div style="text-align: justify;">Try to play this URK in windows media player. If it works – you&#8217;re half way through</div>
</li>
</ol>
<p style="text-align: left;">If you can get the link in any other way, it&#8217;s fine… This is only a suggestion</p>
<p style="text-align: left;"> </p>
<h2 style="text-align: left;">STEP 2 – Set up VLC as a stream server at your home</h2>
<p style="text-align: left;">I will start with an apology. I didn&#8217;t find a proper way to do it with the GUI of version 1.0+.<br />
On the past versions it was relatively clear, so that&#8217;s where I managed to find the command line you need to run in order for it to work<br />
So, at this point, you need to run <a href="http://www.videolan.org/">VLC</a> on your PC with these parameters:</p>
<p style="text-align: left;"><span style="font-family: Courier New;">vlc mms://yourserver/yourlink :sout=#transcode{acodec=mp3,ab=64,channels=2}:duplicate{dst=std{access=mmsh,mux=asfh,dst=:8080}}<br />
</span></p>
<p style="text-align: left;">This will stream the web-radio station to port 8080.<br />
You can test this using Windows Media Player, just open it up, and open the url <a href="mms://localhost:8080">mms://localhost:8080</a></p>
<p style="text-align: left;">Another thing you need to keep in mind, is that you should establish port forwarding if you are behind NAT.</p>
<p style="text-align: left;"> That&#8217;s the whole deal… Of course you can improve it by creating a script that will run it, or add the http interface of VLC to remote control it on another port, but I don&#8217;t want to overload this guide…</p>
<p style="text-align: left;">keep it simple!</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F01%2F29%2Fstream-your-favorite-radio-station-to-your-workplace%2F&amp;linkname=Stream%20your%20favorite%20radio%20station%20to%20your%20workplace"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/01/29/stream-your-favorite-radio-station-to-your-workplace/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Recoloring via Histogram Matching with OpenCV [w/ code]</title>
		<link>http://www.morethantechnical.com/2010/01/28/recoloring-via-histogram-matching-with-opencv-w-code/</link>
		<comments>http://www.morethantechnical.com/2010/01/28/recoloring-via-histogram-matching-with-opencv-w-code/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 10:16:25 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[vision]]></category>
		<category><![CDATA[opencv histogram matching vision graphics code]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=563</guid>
		<description><![CDATA[Hi
I wanted to do the simplest recoloring/color-transfer I could find &#8211; and the internet is just a bust. Nothing free, good and usable available online&#8230; So I implemented the simplest color transfer algorithm in the wolrd &#8211; Histogram Matching.
Here&#8217;s the implementation with OpenCV


// Compute histogram and CDF for an image with mask
void do1ChnHist(const Mat&#38;amp; _i, [...]]]></description>
			<content:encoded><![CDATA[<p>Hi</p>
<p>I wanted to do the simplest recoloring/color-transfer I could find &#8211; and the internet is just a bust. Nothing free, good and usable available online&#8230; So I implemented the simplest color transfer algorithm in the wolrd &#8211; <a href="http://en.wikipedia.org/wiki/Histogram_matching">Histogram Matching</a>.</p>
<p>Here&#8217;s the implementation with OpenCV</p>
<p><span id="more-563"></span></p>
<pre class="brush: plain;">
// Compute histogram and CDF for an image with mask
void do1ChnHist(const Mat&amp;amp; _i, const Mat&amp;amp; mask, double* h, double* cdf) {
Mat _t = _i.reshape(1,1);
Mat _tm;
mask.copyTo(_tm);
_tm = _tm.reshape(1,1);
for(int p=0;p&amp;lt;_t.cols;p++) {
if(_tm.at(0,p) &amp;gt; 0) {
uchar c = _t.at(0,p);
h[c] += 1.0;
}
}

//normalize hist
Mat _tmp(1,256,CV_64FC1,h);
double minVal,maxVal;
minMaxLoc(_tmp,&amp;amp;minVal,&amp;amp;maxVal);
_tmp = _tmp / maxVal;

cdf[0] = h[0];
for(int j=1;j&amp;lt;256;j++) {
cdf[j] = cdf[j-1]+h[j];
}

//normalize CDF
_tmp.data = (uchar*)cdf;
minMaxLoc(_tmp,&amp;amp;minVal,&amp;amp;maxVal);
_tmp = _tmp / maxVal;
}

// match histograms of 'src' to that of 'dst', according to both masks
void histMatchRGB(Mat&amp; src, const Mat&amp; src_mask, const Mat&amp; dst, const Mat&amp; dst_mask) {
#ifdef BTM_DEBUG
	namedWindow(&quot;original source&quot;,CV_WINDOW_AUTOSIZE);
	imshow(&quot;original source&quot;,src);
	namedWindow(&quot;original query&quot;,CV_WINDOW_AUTOSIZE);
	imshow(&quot;original query&quot;,dst);
#endif

	vector&lt;Mat&gt; chns;
	split(src,chns);
	vector&lt;Mat&gt; chns1;
	split(dst,chns1);
	Mat src_hist = Mat::zeros(1,256,CV_64FC1);
	Mat dst_hist = Mat::zeros(1,256,CV_64FC1);
	Mat src_cdf = Mat::zeros(1,256,CV_64FC1);
	Mat dst_cdf = Mat::zeros(1,256,CV_64FC1);
	Mat Mv(1,256,CV_8UC1);
	uchar* M = Mv.ptr&lt;uchar&gt;();

	for(int i=0;i&lt;3;i++) {
		src_hist.setTo(cvScalar(0));
		dst_hist.setTo(cvScalar(0));
		src_cdf.setTo(cvScalar(0));
		src_cdf.setTo(cvScalar(0));

		do1ChnHist(chns[i],src_mask,src_hist,src_cdf);
		do1ChnHist(chns1[i],dst_mask,dst_hist,dst_cdf);

		uchar last = 0;
		double* _src_cdf = src_cdf.ptr&lt;double&gt;();
		double* _dst_cdf = dst_cdf.ptr&lt;double&gt;();

		for(int j=0;j&lt;src_cdf.cols;j++) {
			double F1j = _src_cdf[j];

			for(uchar k = last; k&lt;dst_cdf.cols; k++) {
				double F2k = _dst_cdf[k];
				if(abs(F2k - F1j) &lt; HISTMATCH_EPSILON || F2k &gt; F1j) {
					M[j] = k;
					last = k;
					break;
				}
			}
		}

		Mat lut(1,256,CV_8UC1,M);
		LUT(chns[i],lut,chns[i]);
	}

	Mat res;
	merge(chns,res);

#ifdef BTM_DEBUG
	namedWindow(&quot;matched&quot;,CV_WINDOW_AUTOSIZE);
	imshow(&quot;matched&quot;,res);

	waitKey(BTM_WAIT_TIME);
#endif

	res.copyTo(src);
}
</pre>
<p>Edit 31/1/10: nicer code in histMatch, better memory consumption.</p>
<p>The code is fairly simple.. I started using the OpenCV 2.0 C++ API and I must say it&#8217;s great, not having to worry about silly memory managment, everything is instanced on the stack and get&#8217;s released automatically.</p>
<p>Just a quick overview:</p>
<ul>
<li>Compute histogram and comulative distibution function (CDF) for each image.</li>
<li>Create the lookup table (LUT) from one CDF to the other</li>
<li>Apply the LUT to the image</li>
</ul>
<p>External usage is simple</p>
<pre class="brush: plain;">
Mat src=cvLoadImage(&quot;image008.jpg&quot;);
Mat dst=cvLoadImage(&quot;image003.jpg&quot;);
Mat src_mask = cvLoadImage(&quot;image008_mask.bmp&quot;,0);
Mat dst_mask = cvLoadImage(&quot;image003_mask.bmp&quot;,0);

histMatchRGB(dst,dst_mask,src,src_mask);
</pre>
<p>Enjoy!<br />
Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F01%2F28%2Frecoloring-via-histogram-matching-with-opencv-w-code%2F&amp;linkname=Recoloring%20via%20Histogram%20Matching%20with%20OpenCV%20%5Bw%2F%20code%5D"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/01/28/recoloring-via-histogram-matching-with-opencv-w-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Links of the week</title>
		<link>http://www.morethantechnical.com/2010/01/21/links-of-the-week/</link>
		<comments>http://www.morethantechnical.com/2010/01/21/links-of-the-week/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 12:20:09 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[weekly links]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=561</guid>
		<description><![CDATA[http://www.runnersworld.com/article/1,7124,s6-240-319&#8211;13001-0,00.html
Shoes tying hacks
http://www.engadget.com/2010/01/18/misa-digital-guitar-cuts-the-strings-brings-the-noise/
Very nice! A digital guitar&#8230;
http://www.newscientist.com/article/dn18036
An interesting concept &#8211; see-through walls w/ augmentd reality
http://gizmodo.com/5452140/one-third-of-us-11+year+olds-have-cellphones
The &#8220;Youth market&#8221;&#8217;s little brother &#8211; the &#8220;Toddler market&#8221; &#8211; is booming
http://gizmodo.com/5451876/rumor-apple-iphone-os-40-features-detailed
Some goodies from iPhone OS 4 &#8211; where is video-pixel-bytes access already?!
http://lifehacker.com/5452786/memorize-now-helps-you-commit-long-passages-to-memory
I like! A helper webapp to memorize text
http://gizmodo.com/5452684/voice-band-iphone-app-converts-bah-ba-ba-bah-into&#8212;
This is awesome.
http://gizmodo.com/5453436/googles-html5-youtube-videos-dont-need-flash
YouTube without flash: I tried it on Chrome, the video was [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.runnersworld.com/article/1,7124,s6-240-319--13001-0,00.html">http://www.runnersworld.com/article/1,7124,s6-240-319&#8211;13001-0,00.html<br />
</a>Shoes tying hacks</p>
<p><a href="http://www.engadget.com/2010/01/18/misa-digital-guitar-cuts-the-strings-brings-the-noise/">http://www.engadget.com/2010/01/18/misa-digital-guitar-cuts-the-strings-brings-the-noise/</a><br />
Very nice! A digital guitar&#8230;</p>
<p><a href="http://www.newscientist.com/article/dn18036">http://www.newscientist.com/article/dn18036</a><br />
An interesting concept &#8211; see-through walls w/ augmentd reality</p>
<p><a href="http://gizmodo.com/5452140/one-third-of-us-11+year+olds-have-cellphones">http://gizmodo.com/5452140/one-third-of-us-11+year+olds-have-cellphones</a><br />
The &#8220;Youth market&#8221;&#8217;s little brother &#8211; the &#8220;Toddler market&#8221; &#8211; is booming</p>
<p><a href="http://gizmodo.com/5451876/rumor-apple-iphone-os-40-features-detailed ">http://gizmodo.com/5451876/rumor-apple-iphone-os-40-features-detailed<br />
</a>Some goodies from iPhone OS 4 &#8211; where is video-pixel-bytes access already?!</p>
<p><a href="http://lifehacker.com/5452786/memorize-now-helps-you-commit-long-passages-to-memory ">http://lifehacker.com/5452786/memorize-now-helps-you-commit-long-passages-to-memory<br />
</a>I like! A helper webapp to memorize text</p>
<p><a href="http://gizmodo.com/5452684/voice-band-iphone-app-converts-bah-ba-ba-bah-into---">http://gizmodo.com/5452684/voice-band-iphone-app-converts-bah-ba-ba-bah-into&#8212;<br />
</a>This is awesome.</p>
<p><a href="http://gizmodo.com/5453436/googles-html5-youtube-videos-dont-need-flash ">http://gizmodo.com/5453436/googles-html5-youtube-videos-dont-need-flash<br />
</a>YouTube without flash: I tried it on Chrome, the video was choppy, volume control didn&#8217;t work proerly and the progressing download &amp; play made the position marker bounce around. But in the end, anything that replaces Flash, and Adobe&#8217;s reign over internet interactive animation,  is good..</p>
<p>C ya&#8217;ll next week!</p>
<p>Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F01%2F21%2Flinks-of-the-week%2F&amp;linkname=Links%20of%20the%20week"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/01/21/links-of-the-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Never fear – the links are here [Links of the week]</title>
		<link>http://www.morethantechnical.com/2010/01/07/never-fear-the-links-are-here-links-of-the-week/</link>
		<comments>http://www.morethantechnical.com/2010/01/07/never-fear-the-links-are-here-links-of-the-week/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 16:44:16 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[weekly links]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=559</guid>
		<description><![CDATA[Hi
Stuff I picked up on the web the last week:
 http://www.billshrink.com/blog/nexus-one-vs-iphone-droid-palm-pre-total-cost-of-ownership/
Compare the leading smartphones on the market
http://www.techcrunch.com/2010/01/05/quantcast-mobile-web-apple-android/
Mobile web usage stats: iPhone 65%, Android 12%, RIM 9%
http://gizmodo.com/5442217/the-invisible-oled-laptop-to-end-all-laptops
A transparent screen – Cool? yes. Practical? Not so much.
http://www.techcrunch.com/2010/01/06/augmented-reality-vs-virtual-reality/
Augmented reality is officially more popular than virtual reality.
http://gizmodo.com/5439721/new-touchless-mobile-interface-could-eliminate-fingerprint-smudging-forever
You don&#8217;t need a mouse anymore (if you have a 154 frames-per-second camera, [...]]]></description>
			<content:encoded><![CDATA[<p>Hi</p>
<p>Stuff I picked up on the web the last week:<br />
<a href="http://www.billshrink.com/blog/nexus-one-vs-iphone-droid-palm-pre-total-cost-of-ownership/"> http://www.billshrink.com/blog/nexus-one-vs-iphone-droid-palm-pre-total-cost-of-ownership/</a><br />
Compare the leading smartphones on the market</p>
<p><a href="http://www.techcrunch.com/2010/01/05/quantcast-mobile-web-apple-android/">http://www.techcrunch.com/2010/01/05/quantcast-mobile-web-apple-android/</a><br />
Mobile web usage stats: iPhone 65%, Android 12%, RIM 9%</p>
<p><a href="http://gizmodo.com/5442217/the-invisible-oled-laptop-to-end-all-laptops">http://gizmodo.com/5442217/the-invisible-oled-laptop-to-end-all-laptops</a><br />
A transparent screen – Cool? yes. Practical? Not so much.</p>
<p><a href="http://www.techcrunch.com/2010/01/06/augmented-reality-vs-virtual-reality/">http://www.techcrunch.com/2010/01/06/augmented-reality-vs-virtual-reality/</a><br />
Augmented reality is officially more popular than virtual reality.</p>
<p><a href="http://gizmodo.com/5439721/new-touchless-mobile-interface-could-eliminate-fingerprint-smudging-forever">http://gizmodo.com/5439721/new-touchless-mobile-interface-could-eliminate-fingerprint-smudging-forever</a><br />
You don&#8217;t need a mouse anymore (if you have a 154 frames-per-second camera, and very steady hands)</p>
<p><a href="http://gizmodo.com/5442385/samsung-projector-phone-in-action">http://gizmodo.com/5442385/samsung-projector-phone-in-action</a><br />
Samsung&#8217;s projector mobile phone in action in CES</p>
<p><a href="http://weblogs.baltimoresun.com/news/technology/2010/01/apple_tablet_3d.html">http://weblogs.baltimoresun.com/news/technology/2010/01/apple_tablet_3d.html</a><br />
Apple is putting proximity sensors on new device to allow for 3D desktop manipulation.</p>
<p><a href="http://gizmodo.com/5441682/att-sdk-for-dumbphones-announced">http://gizmodo.com/5441682/att-sdk-for-dumbphones-announced</a><br />
AT&amp;T goes app-store on dumbphones, releases SDK for BREW</p>
<p>C y&#8217;all next week!</p>
<p>Roy</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F01%2F07%2Fnever-fear-the-links-are-here-links-of-the-week%2F&amp;linkname=Never%20fear%20%26%238211%3B%20the%20links%20are%20here%20%5BLinks%20of%20the%20week%5D"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/01/07/never-fear-the-links-are-here-links-of-the-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Just links [Links of the week]</title>
		<link>http://www.morethantechnical.com/2009/12/27/just-links-links-of-the-week/</link>
		<comments>http://www.morethantechnical.com/2009/12/27/just-links-links-of-the-week/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 11:41:20 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[weekly links]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=557</guid>
		<description><![CDATA[Hi
Stuff I picked up on the web the last week:
http://www.techcrunch.com/2009/12/21/world-map-social-networks/
Never tired of infographics: World map of social networks
http://gizmodo.com/5429631/implausible-digital-forensics-in-tv-and-film-a-medley
Awe-some and then some. Enhance.
http://lifehacker.com/5431998/ribbit-app-delivers-voicemail-transcripts-to-your-iphone
Give Ribbit credit for the bold stand in front of G-Voice.
http://gizmodo.com/5428610/rumor-google-working-on-chrome-os+branded-netbook-with-one-secret-manufacturer
A G netbook! That&#8217;s what we&#8217;ve been missing! Not.
http://gizmodo.com/5428642/apple-patent-sees-you-computing-hands+free-in-3d
3D interface by Apple, based on position of user.
http://gizmodo.com/5433074/open-apps-on-a-virtual-iphone-thanks-to-augmented-reality
Orange Israel promoting iPhones in a cute way: [...]]]></description>
			<content:encoded><![CDATA[<p>Hi</p>
<p>Stuff I picked up on the web the last week:</p>
<p><a href="http://www.techcrunch.com/2009/12/21/world-map-social-networks/" target="_blank">http://www.techcrunch.com/2009/12/21/world-map-social-networks/</a><br />
Never tired of infographics: World map of social networks</p>
<p><a href="http://gizmodo.com/5429631/implausible-digital-forensics-in-tv-and-film-a-medley" target="_blank">http://gizmodo.com/5429631/implausible-digital-forensics-in-tv-and-film-a-medley</a><br />
Awe-some and then some. Enhance.</p>
<p><a href="http://lifehacker.com/5431998/ribbit-app-delivers-voicemail-transcripts-to-your-iphone" target="_blank">http://lifehacker.com/5431998/ribbit-app-delivers-voicemail-transcripts-to-your-iphone</a><br />
Give Ribbit credit for the bold stand in front of G-Voice.</p>
<p><a href="http://gizmodo.com/5428610/rumor-google-working-on-chrome-os+branded-netbook-with-one-secret-manufacturer" target="_blank">http://gizmodo.com/5428610/rumor-google-working-on-chrome-os+branded-netbook-with-one-secret-manufacturer</a><br />
A G netbook! That&#8217;s what we&#8217;ve been missing! Not.</p>
<p><a href="http://gizmodo.com/5428642/apple-patent-sees-you-computing-hands+free-in-3d" target="_blank">http://gizmodo.com/5428642/apple-patent-sees-you-computing-hands+free-in-3d</a><br />
3D interface by Apple, based on position of user.</p>
<p><a href="http://gizmodo.com/5433074/open-apps-on-a-virtual-iphone-thanks-to-augmented-reality" target="_blank">http://gizmodo.com/5433074/open-apps-on-a-virtual-iphone-thanks-to-augmented-reality</a><br />
Orange Israel promoting iPhones in a cute way: iPhone inside iPhone with AR.</p>
<p><a href="http://www.techcrunch.com/2009/12/23/confirmed-jajah-sold-207-million" target="_blank">http://www.techcrunch.com/2009/12/23/confirmed-jajah-sold-207-million</a><br />
JaJah sold to Telefonica (O2) &#8211; for 145 million euros!</p>
<p>See ya&#8217;ll next week!</p>
<p>Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2009%2F12%2F27%2Fjust-links-links-of-the-week%2F&amp;linkname=Just%20links%20%5BLinks%20of%20the%20week%5D"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2009/12/27/just-links-links-of-the-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leenky wiks! [Links of the week]</title>
		<link>http://www.morethantechnical.com/2009/12/17/leenky-wiks-links-of-the-week/</link>
		<comments>http://www.morethantechnical.com/2009/12/17/leenky-wiks-links-of-the-week/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 15:43:33 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Website]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=555</guid>
		<description><![CDATA[Hello people of high measure,
Forth are listed the hyperlinks thy humble servant hath collected in past days:
http://gizmodo.com/5423006/i-cant-stop-smiling-over-google-chromes-new-ad
Nice ad by G for Chrome!
http://www.techcrunch.com/2009/12/09/geoapi-creation/
Very interesting: huge database of geo-tagged information with API for developers.
http://gizmodo.com/5424468/mits-bidirectional-display-lets-you-control-objects-with-a-wave-of-your-hand
I saw this contraption in the lab and the guy demoed it for me. It&#8217;s strange looking, but an interesting concept.
http://gizmodo.com/5425146/the-real-google-phone-everything-is-different-now
A G phone!
This is [...]]]></description>
			<content:encoded><![CDATA[<p>Hello people of high measure,</p>
<p>Forth are listed the hyperlinks thy humble servant hath collected in past days:</p>
<p><a href="http://gizmodo.com/5423006/i-cant-stop-smiling-over-google-chromes-new-ad">http://gizmodo.com/5423006/i-cant-stop-smiling-over-google-chromes-new-ad</a><br />
Nice ad by G for Chrome!</p>
<p><a href="http://www.techcrunch.com/2009/12/09/geoapi-creation/">http://www.techcrunch.com/2009/12/09/geoapi-creation/</a><br />
Very interesting: huge database of geo-tagged information with API for developers.</p>
<p><a href="http://gizmodo.com/5424468/mits-bidirectional-display-lets-you-control-objects-with-a-wave-of-your-hand">http://gizmodo.com/5424468/mits-bidirectional-display-lets-you-control-objects-with-a-wave-of-your-hand</a><br />
I saw this contraption in the lab and the guy demoed it for me. It&#8217;s strange looking, but an interesting concept.</p>
<p><a href="http://gizmodo.com/5425146/the-real-google-phone-everything-is-different-now">http://gizmodo.com/5425146/the-real-google-phone-everything-is-different-now</a><br />
A G phone!<br />
This is only a fraction of the online buzz about…</p>
<p><a href="http://gizmodo.com/5425012/the-pen-de-touch-for-driving-light-cycles">http://gizmodo.com/5425012/the-pen-de-touch-for-driving-light-cycles</a><br />
Air-Pen. Nice implementation. But, is this is how we&#8217;re going to interface with computers in the future? Don&#8217;t think so.</p>
<p><a href="http://www.techcrunch.com/2009/12/14/4g-mobile-network-sweden-teliasonera/">http://www.techcrunch.com/2009/12/14/4g-mobile-network-sweden-teliasonera/</a><br />
Välkommen till Sverige &#8211; LTE! (&#8220;Welcome to Sweden &#8211; LTE!&#8221; in Swedish)<br />
TeliaSonera launching LTE</p>
<p><a href="http://www.techcrunch.com/2009/12/14/the-unofficial-google-text-to-speech-api/">http://www.techcrunch.com/2009/12/14/the-unofficial-google-text-to-speech-api/</a><br />
Free Text-To-Speech from G! Hurrah!</p>
<p><a href="http://gizmodo.com/5425874/fuse-what-your-next-touch-phone-is-going-to-feel-like">http://gizmodo.com/5425874/fuse-what-your-next-touch-phone-is-going-to-feel-like</a><br />
TAT are as usual a good indicator of future UI (Social AR…). This time: 3D UI, haptic interface.</p>
<p><a href="http://gizmodo.com/5426963/the-android-market-is-getting-ready-to-explode">http://gizmodo.com/5426963/the-android-market-is-getting-ready-to-explode</a><br />
Some stats on the Android market, looks good.</p>
<p><a href="http://www.techcrunch.com/2009/12/16/google-browser-size/">http://www.techcrunch.com/2009/12/16/google-browser-size/</a><br />
G seem very committed to making the web better. First tools for webmasters to make their sites faster, and making sure the resolution fits</p>
<p><a href="http://gizmodo.com/5428174/shooting-challenge-anthropomorphism">http://gizmodo.com/5428174/shooting-challenge-anthropomorphism</a><br />
Anthropomorphism: Look at the video, (though it&#8217;s an AD) it will put a smile on your face!<br />
and then go shoot some anthropomorphous objects.</p>
<p><a href="http://gizmodo.com/5428233/microsoft-and-palm-treading-water-while-other-mobile-platforms-grow">http://gizmodo.com/5428233/microsoft-and-palm-treading-water-while-other-mobile-platforms-grow</a><br />
Mobile OS stats (Feb-Oct): Apple and RIM skyrocket! WinMo, Symb, Palm, Android &#8211; stagnate.</p>
<p>Enjoy thy weekend!</p>
<p>Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2009%2F12%2F17%2Fleenky-wiks-links-of-the-week%2F&amp;linkname=Leenky%20wiks%21%20%5BLinks%20of%20the%20week%5D"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2009/12/17/leenky-wiks-links-of-the-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending Justin Talbot’s GrabCut Impl [w/ code]</title>
		<link>http://www.morethantechnical.com/2009/12/14/extending-justin-talbots-grabcut-impl-w-code/</link>
		<comments>http://www.morethantechnical.com/2009/12/14/extending-justin-talbots-grabcut-impl-w-code/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 10:27:25 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Website]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[grabcut]]></category>
		<category><![CDATA[iplimage]]></category>
		<category><![CDATA[opencv]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=550</guid>
		<description><![CDATA[Justin Talbot has done a tremendous job implementing the GrabCut algorithm in C [link to paper, link to code]. I was missing though, the option to load ANY kind of file, not just PPMs and PGMs.
So I tweaked the code a bit to receive a filename and determine how to load it: use the internal [...]]]></description>
			<content:encoded><![CDATA[<p>Justin Talbot has done a tremendous job implementing the GrabCut algorithm in C [<a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;ved=0CAcQFjAA&amp;url=http%3A%2F%2Fresearch.justintalbot.org%2Fpapers%2FGrabcut.pdf&amp;ei=lvklS9j5L8j_4AbH24DiCQ&amp;usg=AFQjCNHHiSn3xg8XkvDRZK0G6HIn0doO8Q" target="_blank">link to paper</a>, <a href="http://research.justintalbot.org/papers/GrabCut.zip" target="_blank">link to code</a>]. I was missing though, the option to load ANY kind of file, not just PPMs and PGMs.<br />
So I tweaked the code a bit to receive a filename and determine how to load it: use the internal P[P|G]M loaders, or offload the work to the OpenCV image loaders that take in many more type. If the OpenCV method is used, the IplImage is converted to the internal GrabCut code representation.</p>
<pre class="brush: plain;">

Image&lt;Color&gt;* load( std::string file_name )
{
 if( file_name.find( &quot;.pgm&quot; ) != std::string::npos )
 {
 return loadFromPGM( file_name );
 }

 else if( file_name.find( &quot;.ppm&quot; ) != std::string::npos )
 {
 return loadFromPPM( file_name );
 }

 else
 {
 return loadOpenCV(file_name);
 }
}

void fromImageMaskToIplImage(const Image&lt;Real&gt;* image, IplImage* ipli) {
 for(int x=0;x&lt;image-&gt;width();x++) {
 for(int y=0;y&lt;image-&gt;height();y++) {
 //Color c = (*image)(x,y);
 Real r = (*image)(x,y);
 CvScalar s = cvScalarAll(0);
 if(r == 0.0) {
 s.val[0] = 255.0;
 }
 cvSet2D(ipli,ipli-&gt;height - y - 1,x,s);
 }
 }
}

Image&lt;Color&gt;* loadIplImage(IplImage* im) {
 Image&lt;Color&gt;* image = new Image&lt;Color&gt;(im-&gt;width, im-&gt;height);
 for(int x=0;x&lt;im-&gt;width;x++) {
 for(int y=0;y&lt;im-&gt;height;y++) {
 CvScalar v = cvGet2D(im,im-&gt;height-y-1,x);
 Real R, G, B;
 R = (Real)((unsigned char)v.val[2])/255.0f;
 G = (Real)((unsigned char)v.val[1])/255.0f;
 B = (Real)((unsigned char)v.val[0])/255.0f;
 (*image)(x,y) = Color(R,G,B);
 }
 }
 return image;
}

Image&lt;Color&gt;* loadOpenCV(std::string file_name) {
 IplImage* im = cvLoadImage(file_name.c_str(),1);
 Image&lt;Color&gt;* i = loadIplImage(im);
 cvReleaseImage(&amp;im);
 return i;
}
</pre>
<p>Well, there&#8217;s nothing fancy here, but it does give you a fully working GrabCut implementation on top of OpenCV&#8230; so there&#8217;s the contribution.</p>
<pre class="brush: plain;">

GrabCutNS::Image&lt;GrabCutNS::Color&gt;* imageGC = GrabCutNS::loadIplImage(orig);
 GrabCutNS::Image&lt;GrabCutNS::Color&gt;* maskGC = GrabCutNS::loadIplImage(mask);

 GrabCutNS::GrabCut *grabCut = new GrabCutNS::GrabCut( imageGC );
 grabCut-&gt;initializeWithMask(maskGC);
 grabCut-&gt;fitGMMs();
 //grabCut-&gt;refineOnce();
 grabCut-&gt;refine();

 IplImage* __GCtmp = cvCreateImage(cvSize(orig-&gt;width,orig-&gt;height),8,1);
 GrabCutNS::fromImageMaskToIplImage(grabCut-&gt;getAlphaImage(),__GCtmp);
 //cvShowImage(&quot;result&quot;,image);
 cvShowImage(&quot;tmp&quot;,__GCtmp);
 cvWaitKey(30);
</pre>
<p>I also added the GrabCutNS namespace, to differentiate the Image class from the rest of the code (that probably has an Image already).</p>
<p>Code is as usual available online in the <a href="http://code.google.com/p/morethantechnical/source/browse/#svn/trunk/GrabCut" target="_blank">SVN repo</a>.</p>
<p>Enjoy!</p>
<p>Roy.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.morethantechnical.com%2F2009%2F12%2F14%2Fextending-justin-talbots-grabcut-impl-w-code%2F&amp;linkname=Extending%20Justin%20Talbot%26%238217%3Bs%20GrabCut%20Impl%20%5Bw%2F%20code%5D"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2009/12/14/extending-justin-talbots-grabcut-impl-w-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
