2011-10-27 19 views
5

ahorro de imagen JPEG utilizando el siguiente código C# EmguCV:EmguCV: cómo especificar la calidad de jpeg al guardar la imagen?

Emgu.CV.Image<Gray, byte> image 
... 
image.Save("imageName.jpg"); 

Pero la imagen se almacena en extremally baja calidad (plaza 1 color por 8x8 píxeles).

Cuando guardo bmp todos están bien:

Emgu.CV.Image<Gray, byte> image 
... 
image.Save("imageName.bmp"); 

cómo aumentar la calidad JPEG cuando se utiliza Emgu.Cv.Image.Save o debería llamar a otra función? ¿Por qué la calidad predeterminada es tan baja?

Intenté preguntar en EmguCV forum, pero es inalcanzable.

+0

Hola, en nombre de EMGU Me disculpo por la página web de estar abajo, pero siempre estoy arrastre aquí y CodeProject para cualquier pregunta que pueda ayudar con. Cheers – Chris

+0

@Chris Muchas gracias. Ahora sé a quién puedo preguntar. Sugerir trabajo estable del sitio! – sergtk

Respuesta

8

EMGU solo tiene imagen.Guardar (nombre de archivo) por lo tanto, tiene que utilizar el método .Net para guardar la imagen. Este código se deriva de here. Separé el código para facilitar que este código abra un archivo y luego intente guardarlo. Esta es la función que le interesa en saveJpeg (SaveFile.FileName, img.ToBitmap(), 100);. Basado en la función saveJpeg (ruta de cadena, imagen de mapa de bits, calidad larga).

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

ahora para obtener el código de esa función proviene de la siguiente puede copiar y pegar esto en su proyecto no se olvide de la instrucción using en la parte superior de su código.

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

Este es el mejor método para EMGU si se queda atascado avísame.

espero que esto ayude,

Chris

+0

me parece adecuado. Gracias. De todos modos, algo extraño sucedió con EmguCV: ¿por qué guarda el jpeg con una calidad tan baja? No me puedo dar cuenta. – sergtk

+0

No puedo especificar exactamente que no sea la primera vez que me encuentro con funciones de ahorro de imágenes tan deficientes, de hecho, algunos costosos sistemas MVS usan la misma calidad de compresión. Voy a plantear el asunto, sin embargo, podría no convertirse en una nueva versión ya que este método es bastante específico de la plataforma. Me alegro de haber ayudado, Cheers – Chris

+0

He encontrado cómo reproducir un comportamiento tan extraño. Si la aplicación se ejecuta en VS2010 y el directorio bin contiene highgui210d.dll aparece el problema, si elimino highgui210d.dll todo funciona bien ... – sergtk

-1

Pruebe esto. ¿Y por qué no usa el viejo y bueno OpenCV http://opencv.itseez.com doc?

int quality = 100; // 0 - low, 100 - best 
image.Save("imageName.bmp", CV_IMWRITE_JPEG_QUALITY, quality); 
+1

Lo sentimos, esto no es posible con EMGU y la referencia de OpenCV no es aplicable. – Chris

4

Sobre la base de la respuesta de Chris si alguien está interesado aquí es una extensión sencilla;

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

Uso;

var fname = 0; 
while(true) 
{ 
    try 
    { 
     var img = capture.QueryFrame(); 
     img.Save(String.Format(@"c:\rec\{0}.jpg", ++fname), 100); 
    } catch(Exception) { break; } 
} 
0

Así es como lo hice con Emgu CV:

CvInvoke.Imwrite(path, cvImage, new KeyValuePair<ImwriteFlags, int> (ImwriteFlags.JpegQuality, quality)); 
Cuestiones relacionadas