Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EmguCV - how to specify jpeg quality when saving image?

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.

like image 659
sergtk Avatar asked Oct 27 '11 09:10

sergtk


3 Answers

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

like image 186
Chris Avatar answered Nov 19 '22 18:11

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; }
}
like image 5
expelledboy Avatar answered Nov 19 '22 19:11

expelledboy


Here's how I did with Emgu CV:

CvInvoke.Imwrite(path, cvImage, new KeyValuePair<ImwriteFlags, int> (ImwriteFlags.JpegQuality, quality));
like image 3
Alon Catz Avatar answered Nov 19 '22 19:11

Alon Catz