I save jpeg image using the following C# EmguCV code:
Emgu.CV.Image<Gray, byte> image
...
image.Save("imageName.jpg");
But image is stored in extremally low quality (1 color square per 8x8 pixels).
When I save bmp all are ok:
Emgu.CV.Image<Gray, byte> image
...
image.Save("imageName.bmp");
How to increase jpeg quality when using Emgu.Cv.Image.Save
or should I call other function?
Why is default quality so low?
Tried to ask on EmguCV forum, but it is unreachable.
EMGU only has image.Save(filename) therefore you have to use the .Net method of saving the image. This code is derived from here. I separated the code for ease this code opens a file then attempts to save it. This is the function you interested in saveJpeg(SaveFile.FileName, img.ToBitmap(), 100);. Based on the function saveJpeg(string path, Bitmap img, long quality).
open.Filter = "Image Files (*.tif; *.dcm; *.jpg; *.jpeg; *.bmp)|*.tif; *.dcm; *.jpg; *.jpeg; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
Image<Bgr, Byte> img = new Image<Bgr, Byte>(open.FileName);
SaveFileDialog SaveFile = new SaveFileDialog();
if (SaveFile.ShowDialog() == DialogResult.OK)
{
saveJpeg(SaveFile.FileName, img.ToBitmap(), 100);
}
}
Now to get the code for that function comes from the following you can copy and paste this into your project don't forget the using statement at the top of your code.
using System.Drawing.Imaging;
private void saveJpeg(string path, Bitmap img, long quality)
{
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
// Jpeg image codec
ImageCodecInfo jpegCodec = this.getEncoderInfo("image/jpeg");
if (jpegCodec == null)
return;
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
}
private ImageCodecInfo getEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
This is the best method for EMGU if you get stuck let me know.
Hope this Helps,
Chris
Building on Chris's answer if anyone is interested here is a simple extention;
using System;
using System.Linq;
using System.Drawing.Imaging;
using Emgu.CV.Structure;
public static class EmguImageSave
{
/// <summary>
/// Save a jpeg image with a specified quality
/// </summary>
/// <param name="path">Name of the file to which to save the image</param>
/// <param name="quality">Byte that specifies JPEG Quality of the image encoder</param>
public static void Save( this Emgu.CV.Image<Bgr, Byte> img, string filename, double quality )
{
var encoderParams = new EncoderParameters( 1 );
encoderParams.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality,
(long)quality
);
var jpegCodec = (from codec in ImageCodecInfo.GetImageEncoders()
where codec.MimeType == "image/jpeg"
select codec).Single();
img.Bitmap.Save( filename, jpegCodec, encoderParams );
}
}
Usage;
var fname = 0;
while( true )
{
try
{
var img = capture.QueryFrame();
img.Save( String.Format( @"c:\rec\{0}.jpg", ++fname), 100 );
} catch( Exception ) { break; }
}
Here's how I did with Emgu CV:
CvInvoke.Imwrite(path, cvImage, new KeyValuePair<ImwriteFlags, int> (ImwriteFlags.JpegQuality, quality));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With