[VS版本]LeapMotion配置和第一个C++程序(OpenCv辅助)

时间:2024-04-03 08:54:03

1.安装LeapMotion的驱动和下载官方SDK(这个就不给链接了,想要的留邮箱吧)

2.新建Win32程序,先配置好OpenCv环境

3.开始配置leap motion(下面的代码例子是官方实例,不过我加了一个opencv)

  3.1在属性页--》vc++目录配置SDK中的include文件夹和lib文件夹路径

[VS2013版本]LeapMotion配置和第一个C++程序(OpenCv辅助)

[VS2013版本]LeapMotion配置和第一个C++程序(OpenCv辅助)

     3.2直接生成,然后将dll全部拷贝过来

[VS2013版本]LeapMotion配置和第一个C++程序(OpenCv辅助)

4.配置完成后,我们开始使用

   使用十分简单,leap.h提供了一个Controller类用来间接调用leapmotion 的功能,我们只需要继承一个listen类,然后被调用即可

SampleListener.h

#pragma once
#include "Leap.h"
#include <opencv2/opencv.hpp>
using namespace Leap;
using namespace cv;

class CSampleListener : public Listener
{
public:
	CSampleListener();
	~CSampleListener();

	Frame m_SrcFrame;
	Mat m_HandImg;
public:
	virtual void onInit(const Controller&);
	virtual void onConnect(const Controller&);
	virtual void onDisconnect(const Controller&);
	virtual void onExit(const Controller&);
	virtual void onFrame(const Controller&);
	virtual void onFocusGained(const Controller&);
	virtual void onFocusLost(const Controller&);
	virtual void onDeviceChange(const Controller&);
	virtual void onServiceConnect(const Controller&);
	virtual void onServiceDisconnect(const Controller&);
	virtual void onServiceChange(const Controller&);
	virtual void onDeviceFailure(const Controller&);
	virtual void onLogMessage(const Controller&, MessageSeverity severity, int64_t timestamp, const char* msg);
};

SampleListener.cpp

#include "stdafx.h"
#include "SampleListener.h"

const std::string fingerNames[] = { "Thumb", "Index", "Middle", "Ring", "Pinky" };
const std::string boneNames[] = { "Metacarpal", "Proximal", "Middle", "Distal" };


CSampleListener::CSampleListener()
{
	m_HandImg = Mat(1000, 1000, CV_8UC3, Scalar(255, 255, 255));
}


CSampleListener::~CSampleListener()
{
}

void CSampleListener::onInit(const Controller& controller) {
	std::cout << "Initialized" << std::endl;
}

void CSampleListener::onConnect(const Controller& controller) {
	std::cout << "Connected" << std::endl;
}

void CSampleListener::onDisconnect(const Controller& controller) {
	// Note: not dispatched when running in a debugger.
	std::cout << "Disconnected" << std::endl;
}

void CSampleListener::onExit(const Controller& controller) {
	std::cout << "Exited" << std::endl;
}

void CSampleListener::onFrame(const Controller& controller) {
	// Get the most recent frame and report some basic information
	//const Frame frame = controller.frame();
	m_SrcFrame=controller.frame();
	const Frame frame = m_SrcFrame;
	/*std::cout << "Frame id: " << frame.id()
		<< ", timestamp: " << frame.timestamp()
		<< ", hands: " << frame.hands().count()
		<< ", extended fingers: " << frame.fingers().extended().count() << std::endl;
*/
	Mat bImg(800, 800, CV_8UC3, Scalar(255, 255, 255));
	HandList hands = frame.hands();
	for (HandList::const_iterator hl = hands.begin(); hl != hands.end(); ++hl) {
		// Get the first hand
		const Hand hand = *hl;
		//std::string handType = hand.isLeft() ? "Left hand" : "Right hand";
		//std::cout << handType << " ID:" << hand.id() << std::endl;
		//std::cout << std::string(2, ' ') << handType << ", id: " << hand.id()
		//	<< ", palm position: " << hand.palmPosition() << std::endl;
		// Get the hand's normal vector and direction
		const Leap::Vector normal = hand.palmNormal();
		const Leap::Vector direction = hand.direction();

		//Point center = Point(normal[0] + 320, normal[2] + 240);
		//float r = normal[1] / 2;
		//circle(m_HandImg, center, r, Scalar(0, 0, 0));
		//std::cout << normal[0] << "," << normal[1] << "," << "," << normal[2]<<std::endl;
		//imshow("控制画图", m_HandImg);
		//waitKey(30);
		
		// Get fingers
		const FingerList fingers = hand.fingers();
		
		for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); ++fl)
		{
			const Finger finger = *fl;
			/*
			std::cout << std::string(4, ' ') <<  fingerNames[finger.type()]
			<< " finger, id: " << finger.id()
			<< ", length: " << finger.length()
			<< "mm, width: " << finger.width() << std::endl;
			*/
			
			// Get finger bones
			for (int b = 0; b < 4; ++b) {
				Bone::Type boneType = static_cast<Bone::Type>(b);
				Bone bone = finger.bone(boneType);
		       
				Leap::Vector middle = bone.center();
				//std::cout << boneNames[boneType] << std::endl;
				std::cout << middle[0] << "," << middle[1] << "," << "," << middle[2] << std::endl;
				//为什么要加300,为了把效果移动到*
				Point center = Point(middle[0]+300, middle[1]+300);
				circle(bImg, center, 8, Scalar(0, 0, 0),-1);
                //得到,掌心的球的坐标,一样移动300
				const Leap::Vector normal1=hand.sphereCenter();
				circle(bImg, Point(normal1[0] + 300, normal1[1] + 300), 50, Scalar(255, 0, 0));

			}
			
		}
	
	}
	imshow("控制效果", bImg);
	waitKey(30);
	if (!frame.hands().isEmpty()) {
		std::cout << std::endl;
	}

}

void CSampleListener::onFocusGained(const Controller& controller) {
	std::cout << "Focus Gained" << std::endl;
}

void CSampleListener::onFocusLost(const Controller& controller) {
	std::cout << "Focus Lost" << std::endl;
}

void CSampleListener::onDeviceChange(const Controller& controller) {
	std::cout << "Device Changed" << std::endl;
	const DeviceList devices = controller.devices();

	for (int i = 0; i < devices.count(); ++i) {
		std::cout << "id: " << devices[i].toString() << std::endl;
		std::cout << "  isStreaming: " << (devices[i].isStreaming() ? "true" : "false") << std::endl;
		std::cout << "  isSmudged:" << (devices[i].isSmudged() ? "true" : "false") << std::endl;
		std::cout << "  isLightingBad:" << (devices[i].isLightingBad() ? "true" : "false") << std::endl;
	}
}

void CSampleListener::onServiceConnect(const Controller& controller) {
	std::cout << "Service Connected" << std::endl;
}

void CSampleListener::onServiceDisconnect(const Controller& controller) {
	std::cout << "Service Disconnected" << std::endl;
}

void CSampleListener::onServiceChange(const Controller& controller) {
	std::cout << "Service Changed" << std::endl;
}

void CSampleListener::onDeviceFailure(const Controller& controller) {
	std::cout << "Device Error" << std::endl;
	const Leap::FailedDeviceList devices = controller.failedDevices();

	for (FailedDeviceList::const_iterator dl = devices.begin(); dl != devices.end(); ++dl) {
		const FailedDevice device = *dl;
		std::cout << "  PNP ID:" << device.pnpId();
		std::cout << "    Failure type:" << device.failure();
	}
}

void CSampleListener::onLogMessage(const Controller&, MessageSeverity s, int64_t t, const char* msg) {
	switch (s) {
	case Leap::MESSAGE_CRITICAL:
		std::cout << "[Critical]";
		break;
	case Leap::MESSAGE_WARNING:
		std::cout << "[Warning]";
		break;
	case Leap::MESSAGE_INFORMATION:
		std::cout << "[Info]";
		break;
	case Leap::MESSAGE_UNKNOWN:
		std::cout << "[Unknown]";
	}
	std::cout << "[" << t << "] ";
	std::cout << msg << std::endl;
}

main

int main(int argc, char** argv) {
	// Create a sample listener and controller
	CSampleListener listener;
	Controller controller;

	// Have the sample listener receive events from the controller
	controller.addListener(listener);

	if (argc > 1 && strcmp(argv[1], "--bg") == 0)
		controller.setPolicy(Leap::Controller::POLICY_BACKGROUND_FRAMES);

	controller.setPolicy(Leap::Controller::POLICY_ALLOW_PAUSE_RESUME);

	// Keep this process running until Enter is pressed
	std::cout << "Press Enter to quit, or enter 'p' to pause or unpause the service..." << std::endl;

	bool paused = false;
	while (true) {
		char c = std::cin.get();
		if (c == 'p') {
			paused = !paused;
			controller.setPaused(paused);
			std::cin.get(); //skip the newline
		}
		else
			break;
	}

	// Remove the sample listener when done
	controller.removeListener(listener);

	return 0;
}

效果如下

[VS2013版本]LeapMotion配置和第一个C++程序(OpenCv辅助)

注1:上面的思路主要是,先获取手掌,再获取手指,接着获取骨骼,得到骨骼中心,生成一副手掌图像

注2:官方的API解释地址

https://developer-archive.leapmotion.com/documentation/cpp/index.html

注3:感兴趣的童鞋可以试试opengl做出3d手掌