-
Notifications
You must be signed in to change notification settings - Fork 33
Image Processing
- v0.6 (Current)
- v0.5
Most of the image processing techniques available currently in MMALSharp are based on Matrix Convolutions which can be found on Wikipedia.
public async Task TakePictureManual()
{
MMALCamera cam = MMALCamera.Instance;
using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"))
using (var imgEncoder = new MMALImageEncoder())
using (var nullSink = new MMALNullSinkComponent())
{
cam.ConfigureCameraSettings();
var portConfig = new MMALPortConfig(MMALEncoding.JPEG, MMALEncoding.RGB24, 90);
// Create our component pipeline.
imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);
cam.Camera.StillPort.ConnectTo(imgEncoder);
cam.Camera.PreviewPort.ConnectTo(nullSink);
imgCaptureHandler.Manipulate(context =>
{
context.Apply(new SharpenProcessor());
}, new ImageContext(MMALCameraConfig.StillResolution));
// Camera warm up time
await Task.Delay(2000);
await cam.ProcessAsync(cam.Camera.StillPort);
}
// Only call when you no longer require the camera, i.e. on app shutdown.
cam.Cleanup();
}
There are 3 modes available which provide different strengths of Edge Detection: EDStrength.Low
, EDStrength.Medium
and EDStrength.High
.
public async Task TakePictureManual()
{
MMALCamera cam = MMALCamera.Instance;
using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"))
using (var imgEncoder = new MMALImageEncoder())
using (var nullSink = new MMALNullSinkComponent())
{
cam.ConfigureCameraSettings();
var portConfig = new MMALPortConfig(MMALEncoding.JPEG, MMALEncoding.RGB24, 90);
// Create our component pipeline.
imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);
cam.Camera.StillPort.ConnectTo(imgEncoder);
cam.Camera.PreviewPort.ConnectTo(nullSink);
imgCaptureHandler.Manipulate(context =>
{
context.Apply(new EdgeDetection(EDStrength.High));
}, new ImageContext(MMALCameraConfig.StillResolution));
// Camera warm up time
await Task.Delay(2000);
await cam.ProcessAsync(cam.Camera.StillPort);
}
// Only call when you no longer require the camera, i.e. on app shutdown.
cam.Cleanup();
}
As per the Matrices available on the Wikipedia page, MMALSharp provides functionality for a 3x3 or 5x5 Gaussian Blur matrix convolution.
public async Task TakePictureManual()
{
MMALCamera cam = MMALCamera.Instance;
using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"))
using (var imgEncoder = new MMALImageEncoder())
using (var nullSink = new MMALNullSinkComponent())
{
cam.ConfigureCameraSettings();
var portConfig = new MMALPortConfig(MMALEncoding.JPEG, MMALEncoding.RGB24, 90);
// Create our component pipeline.
imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);
cam.Camera.StillPort.ConnectTo(imgEncoder);
cam.Camera.PreviewPort.ConnectTo(nullSink);
imgCaptureHandler.Manipulate(context =>
{
context.Apply(new GaussianProcessor(GaussianMatrix.Matrix3x3));
}, new ImageContext(MMALCameraConfig.StillResolution));
// Camera warm up time
await Task.Delay(2000);
await cam.ProcessAsync(cam.Camera.StillPort);
}
// Only call when you no longer require the camera, i.e. on app shutdown.
cam.Cleanup();
}
Use the following example to get raw access to the Bayer metadata produced with a JPEG frame. Ensure you pass in the correct camera version to the BayerMetaProcessor
constructor, either CameraVersion.OV5647
or CameraVersion.IMX219
.
public async Task TakePictureManual()
{
MMALCamera cam = MMALCamera.Instance;
using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"))
using (var imgEncoder = new MMALImageEncoder(true))
using (var nullSink = new MMALNullSinkComponent())
{
cam.ConfigureCameraSettings();
var portConfig = new MMALPortConfig(MMALEncoding.JPEG, MMALEncoding.RGB24, 90);
// Create our component pipeline.
imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);
cam.Camera.StillPort.ConnectTo(imgEncoder);
cam.Camera.PreviewPort.ConnectTo(nullSink);
imgCaptureHandler.Manipulate(context =>
{
context.Apply(new BayerMetaProcessor(CameraVersion.OV5647));
}, new ImageContext(MMALCameraConfig.StillResolution));
// Camera warm up time
await Task.Delay(2000);
await cam.ProcessAsync(cam.Camera.StillPort);
}
// Only call when you no longer require the camera, i.e. on app shutdown.
cam.Cleanup();
}
By using the CustomConvolutionProcessor
class, you can create your own custom kernel convolutions and have them applied to an image captured by MMALSharp. Simply pass in the kernel array, kernel width and height and the image will be modified accordingly.
private const int KernelWidth = 3;
private const int KernelHeight = 3;
private double[,] TopSobelKernel = new double[KernelWidth, KernelHeight]
{
{ 1, 2, 1 },
{ 0, 0, 0 },
{ -1, -2, -1 }
};
public async Task TakePictureManual()
{
MMALCamera cam = MMALCamera.Instance;
using (var imgCaptureHandler = new ImageStreamCaptureHandler("/home/pi/images/", "jpg"))
using (var imgEncoder = new MMALImageEncoder())
using (var nullSink = new MMALNullSinkComponent())
{
cam.ConfigureCameraSettings();
var portConfig = new MMALPortConfig(MMALEncoding.JPEG, MMALEncoding.RGB24, 90);
// Create our component pipeline.
imgEncoder.ConfigureOutputPort(portConfig, imgCaptureHandler);
cam.Camera.StillPort.ConnectTo(imgEncoder);
cam.Camera.PreviewPort.ConnectTo(nullSink);
imgCaptureHandler.Manipulate(context =>
{
context.Apply(new CustomConvolutionProcessor(this.TopSobelKernel, KernelWidth, KernelHeight));
}, new ImageContext(MMALCameraConfig.StillResolution));
// Camera warm up time
await Task.Delay(2000);
await cam.ProcessAsync(cam.Camera.StillPort);
}
// Only call when you no longer require the camera, i.e. on app shutdown.
cam.Cleanup();
}