Fingergesten mit OpenNI / OpenCV und Cinder ergeben komische Kontur

Darian

Erfahrenes Mitglied
Hallo Leute,

arbeite gerade mit dem Microsoft Kinect und verschiedenen (ja bereits oben erwähnten) Frameworks an verschiedenen Gestenerkennungen.

Leider ist die Kontur meiner Hand immer ziemlich komisch, und ich habe ach öfter mal 6 Finger statt 5. Wäre fein wenn da jemand einen Tipp hätte (Code und Bild kommt weiter unten)

Wie bin ich bis jetzt vorgegangen:

- OpenNI gibt mir die Hand Position
- Tiefendaten um die Hand werden in ein kleineres roi geschnitten
- threshold wird je nach Tiefe der Hand angewendet um alles herum weg zu schneiden
- Kontur der Hand wird mit OpenCV berechnet (mehr habe ich bis jetzt noch nicht)

Vielleicht gibt es auch viel bessere Lösungen dafür. Fertige Frameworks?

Ich habe hier jetzt extrem blöden Shadow Explanation. Die Konturen sind unsauber, und teilweise scheint auch das threshold komische Sachen zu machen. (siehe Bild)

Bitte um Infos bzw. Tipps...

Code Ausschnitt (wird in der draw aufgerufen und für jeden Frame neu berechnet):
PHP:
...
//get depth image
		const XnDepthPixel* depthData = g_DepthGenerator.GetDepthMap();

		cv::Mat mat(frameSize, CV_16UC1, (void*)depthData);
		
		//depthMat is a 16UC1 Mat
		mat.copyTo(depthMat);
		
		//convert to a 8UC1 => one channel Mat
		depthMat.convertTo(depthMat8, CV_8UC1, 255.0f / 3000.0f);
		
		//cv::threshold(depthMat8, depthMat8, 200, 255, cv::THRESH_BINARY);
		//convert from gray to a color image 8UC3
		cvtColor(depthMat8, depthMatBgr, CV_GRAY2RGB);

		//projects the 3D hand position datas to a screen projection
		g_DepthGenerator.ConvertRealWorldToProjective(1, &handPosition, &handPosition);

		if(handRegisterd)
		{
			//cut new 100x100 Mat
			cv::Mat cvRoi(depthMat8, cv::Rect(cv::Point(handPosition.X-50, handPosition.Y-50), cv::Size(100,100)));
			
			//copy roi to a correct CV_8UC1 Mat called
			cvRoi.copyTo(cvRoi2);

			//make thresdhold
			cv::threshold(cvRoi2, cvRoi2, handPosition.Z/10, 255, cv::THRESH_BINARY);

			//new Mat to find the contour => findContours destroys the original Mat (so we use a copy)
			cv::Mat newRoi;
			cvRoi2.copyTo(newRoi);

			//calculate contours
			std::vector<std::vector<cv::Point>> contours;
			cv::findContours(newRoi, // grey level source image
			contours, // a vector of contours
			CV_RETR_EXTERNAL,// retrieve the external contours
			CV_CHAIN_APPROX_NONE);// all pixels of each contours
			
			// Eliminate too short or too long contours
			int cmin= 22; // minimum contour length
			int cmax= 1000; // maximum contour length
		
			std::vector<std::vector<cv::Point> >::const_iterator itc = contours.begin();

			while (itc!=contours.end())
			{
				if (itc->size() < cmin || itc->size() > cmax)
				itc = contours.erase(itc);
			else
				++itc;
			}

			//draw contours
			// Draw black contours on a white image
			cv::Mat result(cvRoi.size(),CV_8UC3,cv::Scalar(255,255,255));
			cv::drawContours(result,contours,
			-1, // draw all contours (hierarchy level)
			cv::Scalar(255,0,0), // in black
			1); // with a thickness of 1

			//draw thresholded hand image
			Channel8u roi = Channel8u(cvRoi.size().width, cvRoi.size().height, cvRoi.size().width, 1, cvRoi.data);
			gl::draw(gl::Texture(roi), Rectf(depthMatBgr.size().width/2, 0, depthMatBgr.size().width/2+cvRoi.size().width*2, cvRoi.size().height*2));

			//draw calculated contour
			Surface8u hullImage = Surface8u(result.data, result.size().width, result.size().height, result.size().width*3, SurfaceChannelOrder::RGB);
			gl::draw(gl::Texture(hullImage), Rectf(depthMatBgr.size().width/2, cvRoi.size().height*2, depthMatBgr.size().width/2+cvRoi.size().width*2, cvRoi.size().height*2+hullImage.getHeight()*2));
		}

		Surface8u image = Surface8u(depthMatBgr.data, depthMatBgr.size().width, depthMatBgr.size().height, depthMatBgr.size().width*3, SurfaceChannelOrder::RGB);

		gl::draw(gl::Texture(image), Rectf(0,0, image.getWidth()/2, image.getHeight()/2));
...

Wäre echt super wenn mir da jemand helfen könnte...

thx und lg
Darian
 

Anhänge

  • fehler.jpg
    fehler.jpg
    38,1 KB · Aufrufe: 49
Zurück