Is there a way to show Kinect Depth Image into Full Screen mode? I'm using C# and WPF, the OpenNI C++ example able to show the dept image in full size with out any stretch occur, but when I use WPF, the image gets stretch out.
Currently I'm getting resolution of 640X480, but I want to display it into any screen size or maybe TV. My laptop is 1280X768 but when u make the image full size it get stretced.
Thanks in advance.
As far as I know the hardware resolution of the Kinect cameras is 640 x 480 so there is no way to increase that without stretching.
In WPF it is possible to scale the image in proportion so the dots of the image remain square.
<Image Source="..." Stretch="Uniform" />
or not scale at all:
<Image Source="..." Stretch="None" />
See Stretching Images under Displaying Images in WPF
Related
I Need to crop and resize an Image in my WPF application as soon as the Picture is loaded.
So, my Basic Image has a VGA size (640x480), and I Need to crop the edges (top by 18 Pixels, bottom by 36 Pixels, left by 48 Pixels, and right by 24 pixels). The new image (which is 568 x 426 pixels) Need to be refitted into the original size (640 x 480 pixels) - basically it's like a digital zoomc that we're using in photography.
I've already found some sample code (Cropping whitespace from image in C#) - this is however a Little bit too complicated since I don't Need to detect the Whitespace on the image. Is there any simple algorithm just by using XAML to do this ?
Thanks in advance.
I think that you should be able to do that by using the Viewbox Class. From the linked page: Defines a content decorator that can stretch and scale a single child to fill the available space. You literally add one to your Window and set your Image as the contents and then you can set properties to control which part of the image it displays:
<ViewBox Width="500" Height="500" Stretch="Uniform">
<Image Source="Images/SomeImage.jpg" Width="300" Height="300"
Margin="-48,-18,-36,-24" />
</ViewBox>
Experiment with the different StretchDirection values and set the Margin to negative values to crop. There are examples in the linked page, but let me know if you need more help.
I would like to know how to overlay two Image objects in Wpf. I've made two streams which output a video, one for bones and another just a normal video. Now I would like to add them together, so the skeleton would be displayed on the color video.
A part of my XAML code is
<Grid Name="layoutGrid">
<Grid Name="VideoGrid" ClipToBounds="True" Background="AliceBlue">
<Image Name="ColorImage" Width="640" Height="480"/>
<Image Name="SkeletalImage" Width="640" Height="480"/>
<Canvas Background="Transparent"/>
</Grid>
<StatusBar VerticalAlignment="Bottom" HorizontalAlignment="Center">
<Button Name="Button1" Content="Skeleton Only" Width="120"/>
</StatusBar>
</Grid>
When I do this, only the Skeletal image is displayed and if I switch the both Images then the color image is shown. It seems like Canvas background doesn't do the trick (to make the black part of skeletal image transparent)
I thought the problem was in my XAML code but it was actually at drawing the transparent background to set the render size. The background for skeleton image was black
dc.DrawRectangle(Brushes.Black, null,
new Rect(0.0, 0.0, RenderWidth, RenderHeight));
instead of transparent
dc.DrawRectangle(Brushes.Transparent, null,
new Rect(0.0, 0.0, RenderWidth, RenderHeight));
that fixed my problem.
Thanks though
I've tried overlaying Skeletal onto color or depth on a canvas, but it never worked out. Instead, when I looked at the Kinect Explorer sample application in the SDK 1.6.0, they overlay using a grid. Unfortunately, I have not learned that much yet, but they used a grid for the color and depth, and a canvas for the skeletal tracking. I can post a snippet if it helps. Good luck!
You are asking basically two different questions: 1) How to display SkeletonStream on a DepthStream, which is very easy, 2) How to display SkeletonStream on a ColorStream, which is still easy but a little more complicated.
Answer to Question 1) The XYZ Vectors of the joints in the skeletal streams are in the same coordinate system as the Depth Stream. So if you plot the Deapth Stream as a quadratic mesh using the focal length of the depth camera from the Kinect SDK, you can plot the skeleton as a line plot in the same coordinate system. The source code that implements exactly what you want to do in OpenGL is available here that will give you an idea how to implement this in wpf.
Answer to Question 2) The video camera has a different field of view from the depth camera. To display the skeleton stream to the ColorStream you need first to map the XYZ vectors of the joints in the skeletal streams to the coordinate system of the depth stream and then draw first the video frame in the background and the skeleton as a line plot on the front.
You can easily do the mapping using the U-V texture coordinates given by the Kinect SDK. See how you can get the UV here.
I am adding Image instances to a Canvas in Windows Runtime environment and my image keeps getting scaled up when in 140 and 180 scale resolution displays, it looks perfect in scale resolution 100. I tried creating 3 PNG images, one for each scale size: 100, 140, 180 but it still scales them up and they look blurry. I created a test image with 4 black pixels on a cyan background and I took a screenshot from the simulator, see how the image is blurry, my original image has just 4 perfect black pixels:
I tried changing the stretch mode of my Image objects, but it does nothing. I'm using this code to add the images at runtime:
var bitmapImage = new BitmapImage();
StorageFile bitmapFile = await StorageFile.GetFileFromApplicationUriAsync(imageUri);
await bitmapImage.SetSourceAsync(await bitmapFile.OpenReadAsync());
Image image = new Image{ Source = bitmapImage};
image.SetValue(Canvas.LeftProperty, x);
image.SetValue(Canvas.TopProperty, y);
canvas.Children.Add(image);
How do I get the images to draw pixel perfectly in the canvas without scaling and at the exact x/y coordinates I want?
I think I have a workaround, but it requires two steps:
First I have to load the image using a more a standard way that doesn't involve getting the file path like so.
var bitmapImage = new BitmapImage(imageUri);
Somehow this must retain more information internally that this image came from a file with the corresponding ResolutionScale for the current display. Thus when it is drawn by the canvas it is not scaled at all. However this only solves half the problem.
The next problem is that the x, y coordinates used to specify where the image is drawn are being scaled so the image is drawn in the wrong place, further than where I wanted. The only thing I can figure to do is unscale them first like so:
var resScale = DisplayInformation.GetForCurrentView().ResolutionScale;
Image image = new Image{ Source = bitmapImage};
image.SetValue(Canvas.LeftProperty, (x * 100.0) / (int)resScale);
image.SetValue(Canvas.TopProperty, (y * 100.0) / (int)resScale);
canvas.Children.Add(image);
The whole thing seems a bit crazy but it seems to work so far... Anyone have a better solution or an explanation why all this is necessary? Seems like the Canvas class needs an unscaled mode that doesn't mess with the images or coordinates across different resolution displays.
UPDATE: This doesn't work perfectly, using a double to store the value results in precision loss and sometimes there are anti-aliasing artifacts. This is not acceptable if you want pixel perfect graphics. I am still looking for a perfect solution.
There are a few more things that might help with your solution.
Use UseLayoutRounding="False" on your image.
Put your Canvas in a full-screen Viewbox, then set the Canvas Width and Height to the screen resolution. You'd use unscaled Canvas.Left/Top values in this case.
Use Direct2D/Direct3D for rendering.
Good luck.
You can change the Stretch property to "None", If you image is still meshed-up:
You should look at what DPI it is saved on. WPF tries to be DPI-independend, so it tries to draw an image of 5"x5" on every monitor the same size. Even when the resolution is higher, it still should be 5"x5" only a high resolution would render(rasterize) the image in higher quality.
Here's some info: http://www.wpflearningexperience.com/?p=41
How do I convert a WPF size to physical pixels?
Here's a piece of xaml code
you can always use scale transform from code behind to scale the images to appropriate amount be it less or more.
<Image Canvas.Left="150" Height="170" Width="170" Visibility="Visible" Stretch="None">
<Image.Source >
<BitmapImage UriSource="ms-appx:///Assets/rollingDieSprite.png"></BitmapImage>
</Image.Source>
<Image.RenderTransform>
<ScaleTransform ScaleX="4" ScaleY="4" x:Name="scaleTfDie"></ScaleTransform>
</Image.RenderTransform>
</Image>
in c# code behind you can go for the following
ScaleTransform sc = new ScaleTransform();
sc.ScaleX = 0.9;
sc.ScaleY = 0.9;
imgDieRolling.RenderTransform = sc;
this will control the scaling . try using fill=none . Let me know if it works.
I found this issue quite problematic as well. I'm creating custom bitmaps and drawing them at different positions on the canvas. I couldn't find a way in the XAML, but I found a way using Direct2D. When you set up your D2DContext, there's a function called SetUnitMode(). The default unit mode is "DIPS" which causes all drawing to be scaled. By switching to PIXELS mode, the system stops scaling the drawing and does everything 1:1.
m_d2dContext->SetUnitMode(D2D1_UNIT_MODE_PIXELS);
I have the following:
<Viewbox x:Name="vb" HorizontalAlignment="Center" VerticalAlignment="Center">
<MediaElement x:Name="mc" />
</Viewbox>
To provide an option to zoom the MediaElement's video to the user, I kept the MediaElement inside the ViewBox (By changing the Stretch property of the ViewBox). Doing so causes a low-res video to pixelate.
Does anyone know how can I stop the video from pixelating or implement a different method to zoom the video?
Video will eventually pixelate at some level of zoom just like raster images will. The level of pixelation will also depend on the codec implementation and whether or not it uses hardware acceleration for rendering. MediaElement uses the codecs you have installed in your machine. May I suggest you try a ScaleTransform and see fi that helps? There's a good utorial on it here:
UI Scaling
I'm working on augmented reality and I wanted to know if it was possible to get the camera output in fullscreen with a normal scale. I'm currently able to get a deformed output (everything is larger than in the real world).
Edit:
I found in the PhotoCamera class on msdn that I have to use camera.AvailableResolutions. This returns an IEnumrable of Size, each one being a supported resolution.
Based on your comment:
I do not understand this. Do you mean to say that the aspect ratio is
wrong; squares becoming rectangular? Could it be that you are
displaying/stretching the picture incorrectly?
Yeah that's what I mean, the image is stretched because the camera is taking an image in 640x480 and the screen is in 800x480
In the UI where you display the image, set the Stretch to None, Uniform or UniformToFill. Do not use Fill that will distort the image.
<Image Source="..." Stretch="Uniform" />
See these examples on the MSDN
Each phone has different lens focal length and screen size. There is no API to scale camera output to physical dimensions of real world (to see the world on the screen like through transparent window). Also, the distance from user eyes to the phone is affected to what should be displayed. You could experimentally find average scale factor to best map camera output to phone screen.
EDIT:
From the beginning it was like the question was not about distortions on different screen orientations but like augmented reality problem.