Directdraw: Rotate video stream - c++

Problem
Windows Mobile / Directdraw: Rotate video stream
The video preview is working, all I need now is a way to rotate the image. I think the only way to handle this is to write a custom filter based on CTransformFilter that will rotate the camera image for you. If you can help me to solve this problem, e.g. by helping me to develop this filter with my limited DirectDraw knowledge, the bounty is yours.
Background / Previous question
I'm currently developing an application for a mobile device (HTC HD2, Windows Mobile 6). One of things the program needs to do is to take pictures using the built-in camera. Previously I did this with the CameraCaptureDialog offered by the Windows Mobile 6 SDK, but our customer wants a more user-friendly solution.
The idea is to preview the camera's video stream in a control and take a high resolution picture (>= 2 megapixels) using the camera's photo function, when the control is clicked. We did some research on the topic and found out the best way to accomplish this seems to be using Direct Draw.
The downsides are that I never really used any native windows API and that my C++ is rather bad. In addition to this I read somewhere that the Direct Draw support of HTC phones is particularity bad and you will have to use undocumented native HTC libraries calls to take high quality pictures.
The good news is that a company offered us to develop a control that meets the specifications stated above. They estimated it would take them about 10 days, which lead to the discussion if we could develop this control ourself within a reasonable amount of time.
It's now my job to research which alternative is better. Needless to say it's far too less time to study the whole architecture and develop a demo, which lead me to the following questions:
Questions no longer relevant!
Does any of you have experience with similar projects? What are your recommendations?
Is there a good Direct Draw source code example that deals with video preview and image capturing?

Well if you look at the EZRGB24 sample you get the basics of a simple video transform filter.
There are 2 things you need to do to the sample to get it to do what you want.
1) You need to copy x,y to y,x.
2) You need to tell the media sample that the sample is now Height x Width instead of Width x Height.
Bear in mind that the final image will have exactly the same number of pixels.
To solve 1 is relatively simple. You can calculate the position of a pixel by doing "x + (y * Width)". So you step through each x and y calculate the position that way and then write it to "y + (x * Height)". This will transpose the image. Of course without step2 this will look completely wrong.
To solve 2 you need to get the AM_MEDIA_TYPE of the input sample. You then need to find out what the formatType is (Probably FormatType_VideoInfo or FormatType_VideoInfo2). You can thus cast the pbFormat member of AM_MEDIA_TYPE to either a VIDEOINFOHEADER or a VIDEOINFOHEADER2 (Depending on the FormatType). You need to now set VIDEOINFOHEADER[2]::bmiHeader.biWidth and biHeight to the biHeight and biWidth (respectively) of the input media sample. Everything else should be the same as the input AM_MEDIA_TYPE.
I hope that helps a bit.

This question will help you get some details about DirectDraw. I did some research about this some time ago and the best I could find was this blog post (also mentioned in the above question). The post presents an extension of the CameraCapture sample in the SDK.
However, don't have high expectations. It seems that the preview and the picture taken will only work in small resolution. Although DirectDraw does describe a way of configuring the resolution, there is no guarantee that this will be properly implemented by the driver.
So from my experience what you have read is true. The only way to do it will be to use HTC drivers. So, if you don't want to spend endless days in reverse engineering for a doubtful result, let someone else do the job for you. If you want to give it a shot, try xda-developers forum.

Related

Shouldn't there be some adjustments for google cardboard?

Shouldn't there be some adjustments for google cardboard? With all different sizes of phones and with everyone having a bit of differences in how far apart our eyes are I was looking for a way to re position the two images closer so that it looked better. I don't need to use all the pixels and I'm thinking if you allowed adjustments to the center placement of each view that this could be more usable. As is I have to hold the phone a bit further from me to see a good image.
The Cardboard is open "technology" and you are free to adjust it to your own personal needs - no one is going to do that for you. If you are on a bigger budget, there are cheap plastic headsets available from various manufacturers. I got my headset for around 35$ with shipping.
I personally use a Color Cross but there are many others. Just make sure to look for some with open back, so you can plug in headphones, for example, or use the camera once that becomes a thing. An adjustable phone holder is a big plus, so be on the lookout for that too. Another important thing is adjustable IPD (Inter Pupillary Distance) for the lenses in the headset - some headsets with fixed lense distance gave me the cross-eyed effect. Also, many headsets have adjustable lens-to-phone distance, which also can be important.
Please note that all this is necessary for an okay-ish experience, and for the very best one available, you should get a whole integrated headset, like the Sony Morpherus, Oculus Rift or SteamVR. Also bear in mind that this technology is still in the RnD phase and there are many problems to be solved.
For an interesting read on some of these problems, check this out:
http://media.steampowered.com/apps/valve/2013/MAbrashGDC2013.pdf

Augmented Reality-PC

I recently saw the virtual mirror concept on you tube, I tried it out and researched about it. It seems that the creators have used augmented reality so that people can see the output on their screens. On researching I found out that we identify a pattern on which a 3D image is superimposed.
Question 1:How are they able to superimpose the jewellery and track the face of the person without identifying any pattern?
I also tried to check various libraries that I can use to make a program similar to the one they show. Seems to me that a lot of people are using Android phones and iPhones and making apps that use augmented reality.
Question 2:Is there any way that I can use c++ and try to make a program that uses augmented reality?
Oh, and the most important thing, the link to the application is provided below:
http://www.boutiqueaccessories.com.au/virtual-mirror/w1/i1001664/
Do try it out. Its a good experience. :D
I'm not able to actually try the live demo, but the linked video suggests that they either use some simplified pattern recognition (get the person's outline), or they simply track you based on the initial image (with your position/texture being determined by the outline being shown.
Following the video, it's easy to see that there's no real/advanced AR behind this. The images are simply overlayed or hidden (e.g. in case it's missing track of one ear due to you looking to the side) and they're not transformed (no perspective or resizing happening). They definitely seem to track the head (or features like ears, neck, etc.). depending on your background and surroundings that's actually a rather trivial task.
Question 2: Sure! There are lots of premade toolsets out there, but you could as well use some general image processing library such as OpenCV to do the math. Augmented reality usually uses some kind of pattern (e.g. a card or page with a known pattern) to determine the correct position and transformation for the contents to be added to the image. There are also approaches using the device's orientation and perspective changes in camera images to determine depth/position (I really like this demo).

webcam "still pin" capture

I am trying to replicate the image quality that is achieved when using the Logitech webcam driver to capture a still image.
The Logitech forum has several threads about the subject unfortunately they all point to a website which is down. such as here.
I am currently able to use DirectShow and a frame grabber to capture images, but they are nowhere near the quality of the snapshot button. Could anyone point me to the direction of a working c++/c example of a snapshot button?
After some research I found this about the Still Image pin, is this the correct method for implementing a snapshot like button?
The webcam I am using the c910 and is capable of taking 10 mega-pixel still images.
Thanks for any help.
My best guess, which I'll use to gather some upvotes (or downvotes), and which will be valid until someone disassembles the application or the driver, is:
Something alike http://www1.idc.ac.il/toky/videoproc-07/projects/superres/srproject.html was used at the application level to enhance the resolution of the images collected as a video.
Rationale: having a friend pulling his hair over simpler things inside the driver, I can only imagine how difficult it should be to code such an algorithm INSIDE the driver with extremely limited set of libraries.
I won't mind taking downvotes here, since I'm too interested in this subject, but please have some information available on the subject.
I did not have a chance to deal with this directly, however I suspect that high resolution images captured from the camera are a result of taking a sequence of images followed by "superresolution" post-processing. This functionality might be unavailable via DirectShow API, since it mostly covers video streaming. However, the camera driver might also make it available via Windows Image Acquisition API, where you might have better luck taking oversampled snapshots of the quality you are looking for.

Controlling the individual pixels of a projector

I need to control the individual pixels of a projector (an Infocus IN3104) whose native resolution is 1024x768. I would like to know which subset of functions in C or an APL to do this either by:
Functions that control the individual pixels of the adapter (not the pixels of a window).
A pixel-perfect, 1:1 map from an image file (1024x728) to the adaptor set at the native resolution of the projector.
In a related question ([How can I edit individual pixels in a window?][1]) the answerer Caladain states "Things have come a bit from the old days of direct memory manipulation.". I feel I need to go back to that to achieve my goal.
I don't know enough of the "graphic pipeline" to know what API or software tool to use. I'm overwhelmed by the number of technologies when I search this topic. I program in R, which easily interfaces to C, but would welcome suggestions of subsets of functions in OpenGL or C++ or ..... any other technology?
Or even an full blown application (rendering) which will map without applying a transformation.
For example even MS paint has the >VIEW>Bitmap but I get some transformation applied and I don't get pixel perfect rendering. This projector has DisplayLink digital input and I've also tried to tweek the timing parameters when using the VESA inputs and I don't think the transformation happens in the projector. In any case, using MS paint would not be flexible enough for me.
Platform: Linux or Windows.
I don't see a reason why a full-screen window, e.g. using SDL, wouldn't work. Normal bitmapped graphics is always 1:1, there shouldn't be any weird scaling going on behind your back for a full-screen:ed window.
Since SDL is portable, you should be able to run the same code in Windows or Linux (or any other supported platform).
The usual approach to this problem on current systems is:
Set graphics card to desired resolution
Create borderless full screen window
Draw whatever you want
There's really not much to gain from a "low level access", although it were certainly possible.

Screensaver in C++ with fading image

How can I make a screensaver in C++ that fades an image in and out at random places on the screen with a specified time delay on the fade out?
Multimonitor support would be awesome.
If you have a working code or know where I can get it, it would be great. Otherwise point me in the right direction. I'm looking for a method that has a smooth and not laggy og flickery fade. The screensaver is for Windows XP.
I dont know C++, but I do know AS3, Javascript, and PHP. So I was hoping to relate some of that knowledge to C++.
What should I use to compile it?
First off if you're starting out in C++, don't start with a windows specific compiler like visual c++. Grab a nice cross-platform IDE that comes with a compiler like eclipse or code::blocks. Like any project, you are going to want to split it up into smaller tasks you can complete in stages. Sounds like you have a couple of hurdles.
Lack of C++ Knowledge (we were all here once)
Lack of knowledge about images (very common affliction)
Lack of experience (we'll work on this)
DO NOT let others discourage you. You CAN do this, and probably faster than you think possible. DO read a book or two about C++, you can get by for one project without knowing much but you WILL get frustrated often. Let's break up your project into a set of small goals. As you complete each goal your confidence in C++ will rise.
Image blending
Windows Screen Saver w/ multi-monitor support
Screen Canvas (directx, opengl, bitmaps?)
Timers
First, let's look at the problem of image blending. I assume that you'll want to "fade" the image in question into whatever windows background you have active. If you're going to have a solid-color background, you can just do it by changing the alpha transparency of the image in question between canvas refreshes. Essentially you'll want to average the color values of each pixel in the two images based on your refresh timer. In more direct terms to find the red, green, and blue pixel elements for any resultant pixel (P3)
N = timer ticks per interval (seconds/milliseconds/etc)
T = ticks that have occurred this interval
P1r = red pixel element from image 1
P2r = red pixel element from image 2
P3r = resultant red pixel element for blended image
P1g = green pixel element from image 1
P2g = green pixel element from image 2
P3g = resultant green pixel element for blended image
P1b = blue pixel element from image 1
P2b = blue pixel element from image 2
P3b = resultant blue pixel element for blended image
P3r = ((T/N * P1r) + ((N-T)/N * P2r))/2
P3g = ((T/N * P1g) + ((N-T)/N * P2g))/2
P3b = ((T/N * P1b) + ((N-T)/N * P2b))/2
Now let's look at the problem of windows screen savers and multi-monitor support. These are really two separate problems. Windows screensavers are really only regular .exe compiled files with a certain callback function. You can find many tutorials on setting up your screensaver functions on the net. Multi-monitor support will actually be a concern when you set up your Screen Canvas, which we'll discuss next.
When I refer to the Screen Canvas, I am referring to the area upon which your program will output visual data. All image rendering apps or tutorials will basically refer to this same concept. If you find this particularly interesting, please consider a graduate program or learning course in Computer Vision. Trust me you will not regret it. Anyway, considering the basic nature of your app I would reccommend against using openGL or DirectX, just because each have their own layer of app-specific knowledge you'll need to acquire before they are useful. On the other hand if you want built-in 3d niceties like double buffering and gpu offloading, I'd go with openGL (more platform agnostic). Lots of fun image libraries come as gimmes as well.
As for multi monitor support, this is a tricky but not complicated issue. You're basically just going to set your canvas bounds (screen boundary) to match the geometry of your multiple monitors. Shouldn't be an issue with multiple monitors of the same resolution, may get tricky with mismatched monitor resolutions (might have canvas areas not displayed on screen etc. There are well known algorithms and workarounds for these issues, but perhaps this is beyond the scope of this question.
Finally as to the timers required, this should be the easiest part. Windows and Linux handle time in their own strange ways (WHY doesn't MS implement STRPTIME), so If you are interested in portability I'd use a 3rd party library. Otherwise just use the windows settimer() basic functionality and have your image rendered in the callback function.
Advanced Topic: Hey if you're still reading there are a number of interesting algorithmic improvements you can make to this program. For instance, with your timer going off a set quanta each second, you could cache the first few blended images and save some processing time (our eyes are not terribly good at noticing differentiating between changing color gradients). If you are using openGL, you could cache sets of blended images as display lists (gotta use all that graphics card memory for something right?). Fun stuff, good luck!
"I dont know C++, but I do know AS3, Javascript, and PHP. So I was hoping to relate some of that knowledge to C++."
Oh boy, I suppose you're going to be surprised. To learn C++:
Buy at least one or two very good books (see here). Do not buy books that aren't very good. They'll teach you habits that you would have to unlearn later in order to make further progress.
Expect having to do plenty of hands-on code writing with a lot of reading in between. In the first few weeks, the compiler will spit legions of incomprehensible error messages at you, your code will keep crashing, and seasoned C++ programmers looking at your code will throw up their hands in disgust. And it's always your fault.
Plan a lot of time to learn. And I mean a real lot. No matter how much time you devote, it will take at least a couple of months until you upgrade from "dummy" to "novice".
Imagine having to hammer at it for a couple of years in order to become a real professional, constantly reading books and articles, devoting plenty of time to newsgroups and discussion forums, learning from others, banging your head against every wall surrounding your desk.
Be prepared to learn something you haven't known before at least once every week even after a decade of programming in C++ for a living.
Just for a moment, imagine I might not overstate this.
Edit for clarification: I have up-voted both Hunter Davis' and Elemental's answers, because they're very good, pretty much to the point, and in general the encouragement is supported by me despite my rant up there. In fact, I do not doubt that many are able to hack something together in C/C++ when given a skeleton example even if actually they don't know much of C++. Go ahead and try, there's a good chance you'll come up with a screen saver within reasonable time. But. Being able to "hack something together in C/C++" is far from "having learned C++". (And I mean very far.)
C++ is an incredible complex, mean, and stubborn beast. I also consider it almost breathtakingly beautiful, but in that it probably mirrors the view from a very high mountain: It's pretty hard to get to the point where you're able to appreciate the beauty.
C++ is a complex language and all that sbi indicates is probably true (certainly after 10 years of commercial C++ programming there is still some to learn) BUT I think that if you are confident in another language it should only take a couple of days to:
a) Install one of the compilers mentioned here (I would suggest VC as a quick in to windows programming)
b) Find some sample code of a screen saver that does something simple using the windows GDI (there is some code within the MS documentation on screen savers)
c) Modify this code to do what you want.
In terms of your limited requirement I think you will find that the window GDI++ libraries have sufficient power to do the alpha fades you require smoothly.
I'd look at microsoft c++ express. It's free and pretty capable. You may need to hack it, or get an older version, to produce unmanaged executables.
There are a lot of tutorials available for the rest