using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Matrox.MatroxImagingLibrary;
namespace MDigAutoFocus
{
class Program
{
private const string IMAGE_FILE = MIL.M_IMAGE_PATH + "BaboonMono.mim";
private const int FOCUS_MAX_NB_POSITIONS = 100;
private const int FOCUS_MIN_POSITION = 0;
private const int FOCUS_MAX_POSITION = (FOCUS_MAX_NB_POSITIONS - 1);
private const int FOCUS_START_POSITION = 10;
private const int FOCUS_MAX_POSITION_VARIATION = MIL.M_DEFAULT;
private const int FOCUS_MODE = MIL.M_SMART_SCAN;
private const int FOCUS_SENSITIVITY = 1;
public class DigHookUserData
{
public MIL_ID SourceImage;
public MIL_ID FocusImage;
public MIL_ID Display;
public int Iteration;
};
static void Main(string[] args)
{
MIL_ID MilApplication = MIL.M_NULL;
MIL_ID MilSystem = MIL.M_NULL;
MIL_ID MilDisplay = MIL.M_NULL;
MIL_ID MilSource = MIL.M_NULL;
MIL_ID MilCameraFocus = MIL.M_NULL;
MIL_INT FocusPos = 0;
DigHookUserData UserData = new DigHookUserData();
MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL);
MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilSource);
MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilCameraFocus);
MIL.MbufClear(MilCameraFocus, 0);
MIL.MdispSelect(MilDisplay, MilCameraFocus);
SimulateGrabFromCamera(MilSource, MilCameraFocus, FOCUS_START_POSITION, MilDisplay);
UserData.SourceImage = MilSource;
UserData.FocusImage = MilCameraFocus;
UserData.Iteration = 0;
UserData.Display = MilDisplay;
Console.Write("\nAUTOFOCUS:\n");
Console.Write("----------\n\n");
Console.Write("Automatic focusing operation will be done on this image.\n");
Console.Write("Press <Enter> to continue.\n\n");
Console.ReadKey();
Console.Write("Autofocusing...\n\n");
GCHandle hUserData = GCHandle.Alloc(UserData);
MIL.MdigFocus(MIL.M_NULL, MilCameraFocus, MIL.M_DEFAULT, MoveLensHookFunction, GCHandle.ToIntPtr(hUserData), FOCUS_MIN_POSITION, FOCUS_START_POSITION, FOCUS_MAX_POSITION, FOCUS_MAX_POSITION_VARIATION, FOCUS_MODE + FOCUS_SENSITIVITY, ref FocusPos);
hUserData.Free();
Console.Write("The best focus position is {0}.\n", FocusPos);
Console.Write("The best focus position found in {0} iterations.\n\n", UserData.Iteration);
Console.Write("Press <Enter> to end.\n");
Console.ReadKey();
MIL.MbufFree(MilSource);
MIL.MbufFree(MilCameraFocus);
MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL);
}
static MIL_INT MoveLensHookFunction(MIL_INT HookType, MIL_INT Position, IntPtr UserDataHookPtr)
{
if (!IntPtr.Zero.Equals(UserDataHookPtr))
{
GCHandle hUserData = GCHandle.FromIntPtr(UserDataHookPtr);
DigHookUserData UserData = hUserData.Target as DigHookUserData;
if (HookType == MIL.M_CHANGE || HookType == MIL.M_ON_FOCUS)
{
SimulateGrabFromCamera(UserData.SourceImage, UserData.FocusImage, (int)Position, UserData.Display);
UserData.Iteration++;
}
}
return 0;
}
private const double FOCUS_BEST_POSITION = (FOCUS_MAX_NB_POSITIONS / 2);
static void SimulateGrabFromCamera(MIL_ID SourceImage, MIL_ID FocusImage, MIL_INT Iteration, MIL_ID AnnotationDisplay)
{
int NbSmoothNeeded = 0;
MIL_INT BufType = 0;
MIL_INT BufSizeX = 0;
MIL_INT BufSizeY = 0;
int Smooth = 0;
MIL_ID TempBuffer = MIL.M_NULL;
MIL_ID SourceOwnerSystem = MIL.M_NULL;
NbSmoothNeeded = (int)Math.Abs(Iteration - FOCUS_BEST_POSITION);
BufType = MIL.MbufInquire(FocusImage, MIL.M_TYPE, MIL.M_NULL);
BufSizeX = MIL.MbufInquire(FocusImage, MIL.M_SIZE_X, MIL.M_NULL);
BufSizeY = MIL.MbufInquire(FocusImage, MIL.M_SIZE_Y, MIL.M_NULL);
if (NbSmoothNeeded == 0)
{
MIL.MbufCopy(SourceImage, FocusImage);
}
else if (NbSmoothNeeded == 1)
{
MIL.MimConvolve(SourceImage, FocusImage, MIL.M_SMOOTH);
}
else
{
SourceOwnerSystem = (MIL_ID)MIL.MbufInquire(SourceImage, MIL.M_OWNER_SYSTEM, MIL.M_NULL);
MIL.MbufAlloc2d(SourceOwnerSystem, BufSizeX, BufSizeY, BufType, MIL.M_IMAGE + MIL.M_PROC, ref TempBuffer);
MIL.MimConvolve(SourceImage, TempBuffer, MIL.M_SMOOTH);
for (Smooth = 1; Smooth < NbSmoothNeeded - 1; Smooth++)
{
MIL.MimConvolve(TempBuffer, TempBuffer, MIL.M_SMOOTH);
}
MIL.MimConvolve(TempBuffer, FocusImage, MIL.M_SMOOTH);
MIL.MbufFree(TempBuffer);
}
DrawCursor(AnnotationDisplay, Iteration);
}
private static double CURSOR_POSITION(MIL_INT BufSizeY) { return ((BufSizeY * 7) / 8); }
private const int CURSOR_SIZE = 14;
private static readonly int CURSOR_COLOR = MIL.M_COLOR_GREEN;
static void DrawCursor(MIL_ID AnnotationDisplay, MIL_INT Position)
{
MIL_ID AnnotationImage = MIL.M_NULL;
MIL_INT BufSizeX = 0;
MIL_INT BufSizeY = 0;
MIL_INT n = 0;
MIL.MdispControl(AnnotationDisplay, MIL.M_OVERLAY, MIL.M_ENABLE);
MIL.MdispControl(AnnotationDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT);
MIL.MdispInquire(AnnotationDisplay, MIL.M_OVERLAY_ID, ref AnnotationImage);
MIL.MbufInquire(AnnotationImage, MIL.M_SIZE_X, ref BufSizeX);
MIL.MbufInquire(AnnotationImage, MIL.M_SIZE_Y, ref BufSizeY);
MIL.MgraColor(MIL.M_DEFAULT, CURSOR_COLOR);
n = (BufSizeX / FOCUS_MAX_NB_POSITIONS);
MIL.MgraLine(MIL.M_DEFAULT, AnnotationImage, 0, CURSOR_POSITION(BufSizeY) + CURSOR_SIZE, BufSizeX - 1, CURSOR_POSITION(BufSizeY) + CURSOR_SIZE);
MIL.MgraLine(MIL.M_DEFAULT, AnnotationImage, Position * n, CURSOR_POSITION(BufSizeY) + CURSOR_SIZE, Position * n - CURSOR_SIZE, CURSOR_POSITION(BufSizeY));
MIL.MgraLine(MIL.M_DEFAULT, AnnotationImage, Position * n, CURSOR_POSITION(BufSizeY) + CURSOR_SIZE, Position * n + CURSOR_SIZE, CURSOR_POSITION(BufSizeY));
MIL.MgraLine(MIL.M_DEFAULT, AnnotationImage, Position * n - CURSOR_SIZE, CURSOR_POSITION(BufSizeY), Position * n + CURSOR_SIZE, CURSOR_POSITION(BufSizeY));
}
}
}