[From Bill Powers (2001.08.12.1850 MDT)]
Potential Delphi Users:
Browsing Delphi sites on the web, I found a program for a very simple video
capture program (captures video from a camera and shows it in a small
window on the screen). It only took me about two hours to figure out how to
work it into a Delphi program that would run. Slow, but still ten times
faster than I could do it with Visual C++.
I'm still fuzzy about what happens while you put a program together. You
start out with a blank "Form" screen, and put components on it like buttons
(one for each procedure) and a "panel" (where showing of pictures takes
place). Double-clicking each button after it's defined causes a
corresponding named procedure (or at least a forward reference to a
procedure) to be added to the Unit that is being constructed as a text file
in another window behind the Form window. For example, the button named
"OpenVideo", when double-clicked, produces both
Openvideo: TButton;
and
procedure OpenVideoClick(Sender: TObject);
which are placed in the source code of the Unit. Note that the procedure
name is the button name with "Click" automatically added; also the argument
of the procedure is automatically added (all the procedures have the same
argument).
Note: Buttons have single-word _names_ like "OpenVideo", by which they are
known to the program. They also have _captions_ that show on the button but
don't have to be the same as the names. So the button _named_ OpenVideo_
has "Open Video" written on it (notice the space). I could have captioned
it "Get ready".
I couldn't tell you what the "OpenVideo: TButton;" line above means, but
the second line is a forward declaration of a procedure, in this case a
procedure that evidently is supposed to look up the driver for the hardware
that grabs video frames and initialize it. The forward declaration doesn't
do that -- it's up to the programmer to write a procedure that will open
the video capture hardware for action. The code I found on the web provided
this procedure:
procedure TForm1.OpenVideoClick(Sender: TObject);
begin
hWndC := capCreateCaptureWindowA('My Own Capture Window',
WS_CHILD or WS_VISIBLE ,
Panel1.Left,
Panel1.Top,
Panel1.Width,
Panel1.Height,
Form1.Handle,
0);
if hWndC <> 0 then
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
end;
"TForm1" is the name of the "form" on which the buttons and panel were
initially laid out; it is also defined as an instance of the class "TForm"
of which all these procedures are members. This looks very much like the
C++ programs.
To get this program to run, I first had to define the buttons that called
each routine (the buttons being named OpenVideo,CloseVideo,GrabFrame, and
so on, after I realized they had to correspond to the procedure names in
the software sample. It's lucky that I ran across a random comment to the
effect that the button names and the procedure names in the Unit were
systematically and automatically related!). When the buttons and panel were
all defined and double-clicked to generate the source code, I then deleted
all the source code in the Unit window (!) and pasted in the sample
software. The first part of the Delphi-generated code was essentially
identical to the sample, so I figured that Delphi wouldn't know the
difference. It didn't. There must be a simpler way to use sample programs,
but I haven't found it yet.
When I compiled the program I got a regular window (with the usual buttons
in the corner, sizeable and moveable) without ever having to specify one.
Clicking on the "Open Video" button produced a blank rectangle, and
clicking on "Grab Frame" showed the picture from my finder camera. Hooray.
I put in a "for" loop to send the "grab" message 100 times, and got 100
consecutive frames at the last frame rate programmed into the camera
driver. So adapting this routine to my other telescope-control routines
will not be hard.
···
=======================================================================
I have to confess that this sabbatical from PCT is not completely pure. I'm
working on an optical satellite-tracking program, which will keep a
satellite centered in the field of view, correcting small errors in the
open-loop predictive tracking. A problem is that while tracking the
satellite, lots of faint and bright stars pass through the field of view at
a relatively high speed (around one degree per second), and the image of
the satellite itself, looking like any other star, also varies in
brightness and wanders about somewhat. So how to track it?
I decided to try doing it in a way that is possibly like the way we track
things with our eyes. First we "attend" to some object in the field of
view, which seems to mean that the active control process receives
information from a small part of the visual field while ignoring the rest
of it. Once we have locked onto the small object, the direction of
attention gives us the directional information about the object, which we
can then foveate by moving the eyeball until we are attending to the center
of the visual field.
In this program, the whole field of view is the video picture of the finder
field. The program scans a small square within this field, using one of
several methods for finding the offset of a point image within the square
and moving the square until that image is centered in the square. Only
information inside the small square area is used; everything else is
ignored. When the user (as a higher-order system) moves the mouse to
position the square so it includes a point image, the program then very
quickly ( 2 or 3 iterations) centers the square on the image. Once the
square contains the point-source of light, it will follow it around in the
picture if it moves. More important, if another point-source of light moves
rapidly through the small square, it will perturb the square but the square
will not lose its lock on the relatively slow moving object. This much is
working now.
The x and y position of the small square indicates the position of the
target relative to the center of the field of view. All that remains is to
use that position as an error signal in a control system that moves the
telescope. When the small square is kept in the center of the field of
view, the satellite will necessarily be there, too.
Is that how visual tracking really works? I don't know, but if it does work
that way, I will have a model ready to match to the data.
Best,
Bill P.