/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Example.LFR.CS
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Example.LFR.CS.CameraB
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// A form main.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public partial class FormMain : Form
{
/// The CUDA compute class.
Rx.LFR.Net.CudaCompute[] m_pxCudaCompute;
/// The visualization handles.
int[] m_aiHandles;
/// The camera server class that is able to find attached cameras.
Rx.LFR.Net.CameraServer m_xCamServer;
/// The camera buffers.
Rx.LFR.Net.ImageQueue[] m_xCamBuffers;
/// The threads.
System.Threading.Thread[] m_xThreads;
/// The stream writer.
System.IO.StreamWriter[] m_swLog;
/// The camera controls.
SimpleCameraControl[] m_xCameraControls;
/// true to stop thread.
bool m_bStopThread = false;
/// true if inistialized.
bool m_bInistialized = false;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Constructor.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public FormMain()
{
try
{
InitializeComponent();
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Event handler. Called by FormMain for shown events.
///
///
/// Source of the event.
/// Event information.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void FormMain_Shown(object sender, EventArgs e)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Form main change exposure.
///
///
/// The value.
/// The value.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void FormMain_ChangeExposure(uint uValue, double dValue)
{
// Get the camera from our camera server
Rx.LFR.Net.Camera xCamera = m_xCamServer.GetCamera(uValue);
xCamera.SetProperty(Rx.InteropNet.Runtime30.Camera.EProperty.Exposure, (float) dValue);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Form main change FPS.
///
///
/// The value.
/// The value.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void FormMain_ChangeFPS(uint uValue, double dValue)
{
// Get the camera from our camera server
Rx.LFR.Net.Camera xCamera = m_xCamServer.GetCamera(uValue);
xCamera.SetProperty(Rx.InteropNet.Runtime30.Camera.EProperty.Framerate, (float) dValue);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Form main stop camera.
///
///
/// The value.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void FormMain_StopCamera(uint uValue)
{
// Get the camera from our camera server
Rx.LFR.Net.Camera xCamera = m_xCamServer.GetCamera(uValue);
xCamera.Stop();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Form main start camera.
///
///
/// The value.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void FormMain_StartCamera(uint uValue)
{
// Get the camera from our camera server
Rx.LFR.Net.Camera xCamera = m_xCamServer.GetCamera(uValue);
xCamera.Start();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Uninitialize and free everything when the main form is closed.
///
///
/// Source of the event.
/// Form closing event information.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (m_bInistialized)
{
/************************************************************************/
/* Stop Threads */
/************************************************************************/
m_bStopThread = true;
foreach (System.Threading.Thread xThread in m_xThreads)
{
xThread.Join();
}
/************************************************************************/
/* Close Cameras */
/************************************************************************/
Print.Header("Close Cameras");
for (uint uCameraIndex = 0; uCameraIndex < m_xCamServer.GetCameraCount(); uCameraIndex++)
{
// Stop the capture of the camera
m_xCamServer.GetCamera(uCameraIndex).Stop();
// Close the cameras and release the communication and its required memory
m_xCamServer.GetCamera(uCameraIndex).Close();
}
// Release the camera server to free all found cameras. All cameras are invalid after this call
m_xCamServer.Release();
}
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Executes the image captured action.
///
///
/// The image.
/// The camera index.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OnImageCaptured(Rx.LFR.Net.ConstImage xConstImage, uint uCameraIndex)
{
/************************************************************************/
/* Image Captured */
/************************************************************************/
// ATTENTION:
// All processing done in this callback would prevents the camera from capturing the next image.
// Therefore it's advisable to BUFFER the image here and to process it in another thread.
/************************************************************************/
/* Write into buffer */
/************************************************************************/
if (!m_xCamBuffers[uCameraIndex].CopyIn(xConstImage))
{
// Buffer is full and overwrite is disabled
// This is a lost frame
return;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Write camera information.
///
///
/// Zero-based index of the camera.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CameraInfo(object uCameraIndex)
{
string sLogFile = "Camera_" + System.Convert.ToString(uCameraIndex) + ".txt";
m_swLog[(uint) uCameraIndex] = System.IO.File.AppendText(sLogFile);
// As long as this application is not stopped
while (!m_bStopThread)
{
float fFps = 0.0f;
m_xCamServer.GetCamera((uint) uCameraIndex).GetProperty(Rx.InteropNet.Runtime30.Camera.EProperty.Framerate, out fFps);
float fActualFps = 0.0f;
m_xCamServer.GetCamera((uint) uCameraIndex).GetProperty(Rx.InteropNet.Runtime30.Camera.EProperty.ActualFramerate, out fActualFps);
m_swLog[(uint) uCameraIndex].Write("\r\nActual FPS : ");
m_swLog[(uint) uCameraIndex].WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
m_swLog[(uint) uCameraIndex].WriteLine(":{0}", fFps);
m_swLog[(uint) uCameraIndex].WriteLine(":{0}", fActualFps);
m_swLog[(uint) uCameraIndex].WriteLine("-------------------------------");
System.Threading.Thread.Sleep(1000);
}
m_swLog[(uint) uCameraIndex].Close();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Process the image.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProcessImage(object uCameraIndex)
{
// As long as this application is not stopped
while (!m_bStopThread)
{
try
{
// Wait for the image buffer to be not empty
if (m_xCamBuffers[(uint) uCameraIndex].WaitForNotEmpty(1000))
{
// Get the first image in the Queue
Rx.Net.Image xImage = new Rx.Net.Image();
if (!m_xCamBuffers[(uint) uCameraIndex].MoveOut(xImage))
{
// Wait again! This functions says that it waits until a frame is available
continue;
}
// Get the CUDA compute class for this camera
Rx.LFR.Net.CudaCompute xCudaCompute = m_pxCudaCompute[(uint) uCameraIndex];
// Upload the captured image as the new raw image of all further CUDA computations
xCudaCompute.UploadRawImage(xImage);
// Calculate the desired images
xCudaCompute.Compute_PreProcess();
xCudaCompute.Compute_RefocusBasic();
xCudaCompute.Compute_DepthRay();
xCudaCompute.Compute_DepthMap(Rx.LFR.Net.ESpace.View_Object_Pinhole);
xCudaCompute.Compute_TotalFocus(Rx.LFR.Net.ESpace.View_Object_Pinhole);
xCudaCompute.Compute_Depth3D();
xCudaCompute.Compute_DepthColorCode(Rx.LFR.Net.ESpace.View_Object_Pinhole);
// Get the image access interface. This interface allows:
// * Download CUDA image into host memory
// * Upload a host image to CUDA to overwrite a certain CUDA image
// * Access to CUDA device pointer to do own CUDA image processing
Rx.LFR.Net.ICudaDataImages xImages = (xCudaCompute.GetInterface(Rx.LFR.Net.Interfaces.ECudaCompute.Images)) as Rx.LFR.Net.ICudaDataImages;
// Download images into the host memory
Rx.Net.Image xImgDepthMap = new Rx.Net.Image();
Rx.Net.Image xImgDepthMapColor = new Rx.Net.Image();
Rx.Net.Image xImgRefocus = new Rx.Net.Image();
xImages.Download(Rx.LFR.Net.EImage.DepthMap_View_Object_Pinhole, xImgDepthMap);
xImages.Download(Rx.LFR.Net.EImage.DepthMapColored_View_Object_Pinhole, xImgDepthMapColor);
xImages.Download(Rx.LFR.Net.EImage.RefocusBasic, xImgRefocus);
// Do own host image processing
// ...
// Get CUDA image pointer
//void* pvCudaPointer = xImages.GetImageDevicePointer(Rx.LFR.Net.EImage.DepthMap_View_Object_Pinhole);
// Do own CUDA image processing
// ...
// Show the Image results
CLUViz.Net.Tool.ViewSetImage(m_aiHandles[(uint) uCameraIndex], xImgDepthMapColor);
xImgDepthMapColor.Dispose();
xImage.Dispose();
xImgDepthMap.Dispose();
xImgRefocus.Dispose();
}
else
{
// If the queue is empty show a black image and wait again
Rx.Net.ImageFormat xFormat = new Rx.Net.ImageFormat(100, 100, Rx.InteropNet.Runtime28.EPixelType.Lum, Rx.InteropNet.Runtime28.EDataType.UInt);
Rx.Net.Image xImage = new Rx.Net.Image(xFormat);
xImage.SetZero();
CLUViz.Net.Tool.ViewSetImage(m_aiHandles[0], xImage);
xImage.Dispose();
System.Console.WriteLine("Time out");
}
}
catch (Rx.Net.RxException ex)
{
Print.Header("Exception");
Console.WriteLine("\n\n\nOnImageCaptured Exception:\n\n\n{0}\n\n\n", ex.ToString(true));
System.Environment.Exit(-1);
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Executes the status action.
///
///
/// Source for the.
/// The message.
/// Source for the.
/// The message.
/// Zero-based index of the value.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OnStatus(Rx.LFR.Net.EStatusMsgSrc eSource, Rx.LFR.Net.EStatusMsg eMsg, string sSource, string sMessage, int iValue)
{
// Print the status message
Console.WriteLine("[{0}] {1, " + iValue * 4 + "}", sSource, sMessage);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Event handler. Called by buttonStartExample for click events.
///
///
/// Source of the event.
/// Event information.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void buttonStartExample_Click(object sender, EventArgs e)
{
m_bInistialized = true;
CLUViz.Net.Tool.Init();
/************************************************************************/
/* Authenticate LFR */
/************************************************************************/
Rx.LFR.Net.LightFieldRuntime.Authenticate();
/// Initialize the calibration manager.
Rx.LFR.Net.CalibrationManager.Initialize();
// Enumerate all CUDA devices at the beginning
Rx.LFR.Net.Cuda.EnumerateCudaDevices();
uint uBufferSize = System.Convert.ToUInt32(numUpDownBufferSize.Value);
bool bOverwrite = checkBoxOverride.Checked;
bool bWriteLog = checkBoxWriteLog.Checked;
numUpDownBufferSize.Enabled = false;
checkBoxOverride.Enabled = false;
checkBoxWriteLog.Enabled = false;
buttonStartExample.Enabled = false;
buttonStopExample.Enabled = true;
/************************************************************************/
/* CUDA */
/************************************************************************/
int iCudaDevices = Rx.LFR.Net.Cuda.GetDeviceCount();
Print.Header("CUDA Devices");
for (int iIdx = 0; iIdx < Rx.LFR.Net.Cuda.GetDeviceCount(); iIdx++)
{
Rx.LFR.Net.CudaDevice xCuda = Rx.LFR.Net.Cuda.GetDevice(iIdx);
string sName;
xCuda.GetParams().GetValue(Rx.LFR.Net.Params.ECudaDevice.Name, out sName);
double dClockMHz;
xCuda.GetParams().GetValue(Rx.LFR.Net.Params.ECudaDevice.ClockFrequencyMHz, out dClockMHz);
double dGlobalMemMB;
xCuda.GetParams().GetValue(Rx.LFR.Net.Params.ECudaDevice.TotalGlobalMemoryMB, out dGlobalMemMB);
Console.WriteLine("{0}: {1}, Clock: {2} MHz, Memory: {3} MB", iIdx, sName, dClockMHz, dGlobalMemMB);
}
/************************************************************************/
/* Find Cameras */
/************************************************************************/
Print.Header("Find Cameras");
// Add a status message callback if you are interested in status messages sent by the camera server while finding cameras
m_xCamServer = new Rx.LFR.Net.CameraServer();
m_xCamServer.StatusMessage += OnStatus;
// Start to find cameras. This is an synchronous call and we wait here until the find process has been finished
m_xCamServer.FindCameras();
// Quit the application if there is no camera
if (m_xCamServer.GetCameraCount() == 0)
{
Console.Write("No camera found\n");
return;
}
m_pxCudaCompute = new Rx.LFR.Net.CudaCompute[m_xCamServer.GetCameraCount()];
m_aiHandles = new int[m_xCamServer.GetCameraCount()];
m_xThreads = new System.Threading.Thread[m_xCamServer.GetCameraCount() * (bWriteLog ? 2 : 1)];
m_xCamBuffers = new Rx.LFR.Net.ImageQueue[m_xCamServer.GetCameraCount()];
m_xCameraControls = new SimpleCameraControl[m_xCamServer.GetCameraCount()];
if (bWriteLog)
{
m_swLog = new System.IO.StreamWriter[m_xCamServer.GetCameraCount()];
}
/************************************************************************/
/* Start Cameras */
/************************************************************************/
Print.Header("Start Cameras");
int iAssignedCudaDevice = 0;
for (uint uCameraIndex = 0; uCameraIndex < m_xCamServer.GetCameraCount(); uCameraIndex++)
{
/************************************************************************/
/* Initialize Buffer */
/************************************************************************/
// Create buffer within the given size and with the given overwrite flag
m_xCamBuffers[uCameraIndex] = new Rx.LFR.Net.ImageQueue();
m_xCamBuffers[uCameraIndex].Initialize(uBufferSize, bOverwrite);
// Get the camera from our camera server
Rx.LFR.Net.Camera xCamera = m_xCamServer.GetCamera(uCameraIndex);
// Load the default calibration of the camera (and load the gray image too)
Rx.LFR.Net.Calibration xDefaultCalibration = new Rx.LFR.Net.Calibration();
Rx.LFR.Net.CalibrationManager.LoadDefaultCalibration(xDefaultCalibration, xCamera, true);
Rx.LFR.Net.IParameters calibParams = xDefaultCalibration.GetParams();
// Open the camera. This prepares the communication with the camera and checks the connection of GigE cameras
// This does NOT start the camera stream
xCamera.Open();
// Add a image captured callback. This method gets called for every captured camera image and more details are given there
xCamera.ImageCaptured += OnImageCaptured;
// Assign the CUDA device and the calibration
m_pxCudaCompute[uCameraIndex] = new Rx.LFR.Net.CudaCompute();
m_pxCudaCompute[uCameraIndex].SetCudaDevice(Rx.LFR.Net.Cuda.GetDevice((int) iAssignedCudaDevice));
m_pxCudaCompute[uCameraIndex].ApplyCalibration(xDefaultCalibration, true);
string sName;
(Rx.LFR.Net.Cuda.GetDevice((int) iAssignedCudaDevice)).GetParams().GetValue(Rx.LFR.Net.Params.ECudaDevice.Name, out sName);
// Create the visualization
// If there is one image buffer per camera set the view caption to the camera name;
string sCameraName = Rx.LFR.Net.CalibrationManager.GetCameraName(xCamera);
m_aiHandles[uCameraIndex] = CLUViz.Net.Tool.CreateViewImage((int) uCameraIndex * 1050, 0, 1000, 800, sCameraName);
float fMin = 0.0f;
float fMax = 0.0f;
xCamera.GetPropertyRange(Rx.InteropNet.Runtime30.Camera.EProperty.Framerate, out fMin, out fMax);
xCamera.SetProperty(Rx.InteropNet.Runtime30.Camera.EProperty.Framerate, fMax);
System.Console.WriteLine("Setting Camera {0} to its max FPS: {1}", sCameraName, fMax);
xCamera.GetPropertyRange(Rx.InteropNet.Runtime30.Camera.EProperty.Exposure, out fMin, out fMax);
/************************************************************************/
/* Initialize Control */
/************************************************************************/
m_xCameraControls[uCameraIndex] = new SimpleCameraControl(sCameraName, uCameraIndex, fMax, fMin);
m_xCameraControls[uCameraIndex].StartCamera += FormMain_StartCamera;
m_xCameraControls[uCameraIndex].StopCamera += FormMain_StopCamera;
m_xCameraControls[uCameraIndex].ChangeFPS += FormMain_ChangeFPS;
m_xCameraControls[uCameraIndex].ChangeExposure += FormMain_ChangeExposure;
tableLayoutPanelCameraControls.RowCount++;
tableLayoutPanelCameraControls.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
tableLayoutPanelCameraControls.Controls.Add(m_xCameraControls[uCameraIndex], 0, tableLayoutPanelCameraControls.RowCount - 1);
// Start the camera. Depending on the given trigger mode, the camera starts to capture images or waits for a trigger
xCamera.Start(Rx.InteropNet.Runtime30.Camera.ETriggerMode.Camera_FreeRun);
m_xThreads[uCameraIndex] = new System.Threading.Thread(ProcessImage);
m_xThreads[uCameraIndex].Start(uCameraIndex);
if (bWriteLog)
{
m_xThreads[m_xCamServer.GetCameraCount() + uCameraIndex] = new System.Threading.Thread(CameraInfo);
m_xThreads[m_xCamServer.GetCameraCount() + uCameraIndex].Start(uCameraIndex);
}
Console.WriteLine("--------------------------------------------------------------------------------------------------");
Console.WriteLine("Camera {0} with Index {1} is assigned to cuda device {2} with index {3}.", sCameraName, uCameraIndex, sName, iAssignedCudaDevice);
Console.WriteLine("--------------------------------------------------------------------------------------------------");
if (iAssignedCudaDevice < iCudaDevices - 1)
{
iAssignedCudaDevice++;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Event handler. Called by buttonStopExample for click events.
///
///
/// Source of the event.
/// Event information.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void buttonStopExample_Click(object sender, EventArgs e)
{
Close();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// the print class.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static class Print
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Header.
///
///
/// The string.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static void Header(string sString)
{
Console.Write("\n\n");
Console.Write("====================================================================\n");
Console.Write("=== {0}\n", sString);
Console.Write("====================================================================\n\n");
}
}
}