Channel8u toChannel8u( const Leap::Image& img, bool copyData )
{
	int32_t h = img.height();
	int32_t w = img.width();
	Channel8u channel;
	if ( copyData ) {
		channel = Channel8u( w, h );
		char_traits<uint8_t>::copy( channel.getData(), img.data(), w * h * sizeof( uint8_t ) );
	} else {
		channel = Channel8u( w, h, w * sizeof( uint8_t ), sizeof( uint8_t ), (uint8_t*)img.data() );
	}
	return channel;
}
Exemple #2
0
cimg_library::CImg<unsigned char> convertImage(Leap::Image leap)
{
	auto result = cimg_library::CImg<unsigned char>(leap.data(), leap.width(), leap.height(), 1);
	//result.display();
	auto resizedResult = result.resize(result.width() * 2, result.height() * 2, 1, 3, 1);
	return result;
}
BigDotList::BigDotList(Leap::Image &img) : bigDots()
{
	value = 0;
	const unsigned char *imgData = img.data();
	for (int i = 0; i < img.width()*img.height(); i++) {
		if (imgData[i] < Dot::thres)
			continue;
		int y = i/img.width();
		Dot newDot(Coord(i-y, y));
		bool groupFound = true;
		/* Check if dot belongs to another group */
		std::vector<BigDot> bd;
		std::vector<Dot> d;
		for (std::vector<BigDot>::iterator bd = bigDots.begin();
		    bd != bigDots.end(); ++bd) {
			for (std::vector<Dot>::iterator d = bd->dots.begin();
			     d != bd->dots.begin(); ++d) {
				if (newDot.pos.getDist(d->pos) < Dot::r) {
					bd->add(newDot);
					groupFound = true;
					break;
				}
			}
			if (groupFound) break;
		}
	}
}
void ULeapMotionImageComponent::UpdateImageTexture()
{
	FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe();

	if (Device && Device->IsConnected())
	{
		Device->SetReferenceFrameOncePerTick();
	}
	
	if (Device && Device->IsConnected() && Device->Frame().images().count() > 1)
	{
		Leap::ImageList ImageList = Device->Frame().images();
		
		for (int eye = 0; eye < 2; eye++)
		{
			Leap::Image Image = ImageList[eye];
			bool isRGB = Image.format() != Leap::Image::INFRARED;
			UTexture2D*& Texture = eye ? ImagePassthroughRight : ImagePassthroughLeft;
			UTexture2D*& Distortion = eye ? DistortionTextureRight : DistortionTextureLeft;
			
			// Recreate the image & distortion textures.
			if (!Texture || Image.width() != Texture->PlatformData->SizeX || Image.height() != Texture->PlatformData->SizeY)
			{
				EPixelFormat PixelFormat = !isRGB ? PF_G8 : PF_R8G8B8A8;
				Texture = UTexture2D::CreateTransient(Image.width(), Image.height(), PixelFormat);
				Texture->SRGB = 0;
				Texture->UpdateResource();

				Distortion = BuildDistortionTextures(Image);

				if (isRGB)
				{
					DynamicPassthroughMaterial->SetTextureParameterValue(eye ? TEXT("BaseTextureRGB_Right") : TEXT("BaseTextureRGB"), Texture);
					DynamicPassthroughMaterial->SetScalarParameterValue(TEXT("ImageFormat"), 1.0);
				}
				else
				{
					DynamicPassthroughMaterial->SetTextureParameterValue(eye ? TEXT("BaseTextureIR_Right") : TEXT("BaseTextureIR"), Texture);
					DynamicPassthroughMaterial->SetScalarParameterValue(TEXT("ImageFormat"), -1.0);
				}

				DynamicPassthroughMaterial->SetTextureParameterValue(eye ? TEXT("DistortionTextureRight") : TEXT("DistortionTexture"), Distortion);

				if (GEngine && GEngine->GameViewport && GEngine->GameViewport->Viewport)
				{
					FIntPoint Resolution = GEngine->GameViewport->Viewport->GetSizeXY();
					FLinearColor ScreenRes = FLinearColor(Resolution.X, Resolution.Y, 0.f, 0.f);
					DynamicPassthroughMaterial->SetVectorParameterValue(TEXT("ScreenResolution"), ScreenRes);
				}
				
				AttachDisplaySurface();
			}

			// Extract the image 
			{
				UTexture2D*& Texture = eye ? ImagePassthroughRight : ImagePassthroughLeft;

				const uint8* LeapData = Image.data();
				const int LeapDataSize = Image.width() * Image.height() * Image.bytesPerPixel();

				//Check for dragonfly
				if (!isRGB)
				{
					uint8* Dest = (uint8*)Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
					FMemory::Memcpy(Dest, LeapData, LeapDataSize);
				}
				else
				{
					uint32* Dest = (uint32*)Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
					FMemory::Memcpy(Dest, LeapData, LeapDataSize);
				}

				Texture->PlatformData->Mips[0].BulkData.Unlock();
				Texture->UpdateResource();
			}

			// Hack: need to update distortion texture every frame to handle device flipping.
			UpdateDistortionTextures(Image, Distortion);
		}

		const bool bUsingHmd = GEngine->HMDDevice.IsValid() && GEngine->HMDDevice->IsHeadTrackingAllowed();
		DynamicPassthroughMaterial->SetScalarParameterValue("HorizontalTanHalfFOV", bUsingHmd ? 1.4f : 1.0f);

	}
	else
	{
		// We can't find two images, that might be due to device being detached & maybe exchanged later -- trigger reset.
		ImagePassthroughLeft = nullptr;
		ImagePassthroughRight = nullptr;
		DistortionTextureLeft = nullptr;
		DistortionTextureRight = nullptr;
	}
}
Leap::Vector GetTrackedPoint(Leap::Image image)
{
	Mat img = Mat(image.height(), image.width(), CV_8UC1);
	img.data = (unsigned char*)image.data();

	Mat cimg = img.clone();
	CvSize size = img.size();

	//binary threshold, val = 235
	threshold(img, cimg, 235, 255, 0);
	medianBlur(cimg, cimg, 5);

	//circle detection with contours	
	bool enableRadiusCulling = false;
	int minTargetRadius = 5;
	vector<vector<Point> > contours;
	vector<Vec4i> heirarchy;

	findContours(cimg, contours, heirarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

	size_t count = contours.size();

	//get circle with largest radius
	float radius = 0;
	Point2i center;

	for (int i = 0; i < count; i++)
	{
		Point2f c;
		float r;
		minEnclosingCircle(contours[i], c, r);

		if (!enableRadiusCulling || r >= minTargetRadius)
		{
			if (r > radius) {
				radius = r;
				center = (Point2i)c;
			}
		}
	}

	Leap::Vector res;
	res.x = center.x;
	res.y = center.y;
	res.z = 0;

	/*
	cvtColor(cimg, cimg, CV_GRAY2BGR);

	Scalar red(0, 0, 255);
	Scalar blue(255, 0, 0);

	if (radius > 0) { //circle was found
		circle(cimg, center, radius, red, 1);
		circle(cimg, center, 1, blue, 2);
		//cout << "Center: " << center.x << "; " << center.y << "\n";
	}
	imshow("detected circles", cimg);
	*/
	return res;
}