EmguCV - how to specify jpeg quality when saving image?

15,794

Solution 1

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

Solution 2

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; }
}

Solution 3

Here's how I did with Emgu CV:

CvInvoke.Imwrite(path, cvImage, new KeyValuePair<ImwriteFlags, int> (ImwriteFlags.JpegQuality, quality));
Share:
15,794
Harshil Shukla
Author by

Harshil Shukla

Updated on June 26, 2022

Comments

  • Harshil Shukla
    Harshil Shukla almost 2 years

    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.