Re: [Eqalign-devel] =?iso-8859-1?q?Me_est=E1_dando_guerra_la_QHY?=
Brought to you by:
antoniofga,
isoplut
From: Antonio F. <ant...@ya...> - 2007-10-04 20:41:26
|
Entonces quedamos que una cosa es capturar una imagen para guardarla en 16 bits y otra representarla en un Picturebox, por ejemplo o enviársela al sistema de representación de imágenes de Camera.cs para autoguiar. Para esto último, primero tenemos que debayizar la imagen directamente en un Bitmap 24bbp. Para guardar la imagen lo mejor sería usar FreeImage, crear un contendor de 48bpp para "debayerizarla" (joé con el palabro) ahí. No sé que máscara bayer tiene la Luna (normalmente será RGGB, GRBG, BRGR, GBRB, en una ventana cuadrada) Ya de entrada para saber si estás leyendo bien la imagen, podrías pasarla a 24bbp y representarla en un picturebox sin decodificarla (oiga), así: Bitmap newImg = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(newImg); g.DrawImage(lunaImg, new Point(0,0)); g.Dispose(); picturebox1.Image = newImg; lunaImg.Dispose(); Así sabrás si la cosa va bien. Si es así, entonces debes crearte un algoritmo de decodificación hacia un Bitmap de 24bbp. Te envío un trozo de código que decodifica una imagen raw con microfiltros RGB, pero está pensado para una imagen RGBImage que se representa en una estructura: private float[] data; , en formato de rango {0.0f, 1.0f} (una caca de óptimo, lo sé). Para trabajar directamente con Bitmaps sería algo parecido y más óptimo si bloqueas la imagen con LockBits para trabajar directamente en memoria. Además, sabiendo la máscara de bayer correcta, puedes reescribir el código específico, el código que te envío es genérico. Bueno, ya nos cuentas. Un saludo ----------------------------------------------------------------------------------------------- public void DeBayerRGB(int idxBayerMatrix) { // 0=B 1=G 2=R // RGGB GRBG GBRG BGGR int[, ,] bMatrix = { { { 2, 1 }, { 1, 0 } }, { { 1, 2 }, { 0, 1 } }, { { 1, 0 }, { 2, 1 } }, { { 0, 1 }, { 1, 2 } } }; int[,] bSubMatrix = { { 0, 0 }, { 0, 0 } }; //ventana int npix = this.height * this.width * 3; //tamaño del buffer float[] data2 = new float[npix]; //nuevo datos de la imagen float int x, y; int idx, idx0, idx1; int idxR = 0, idxG = 0, idxB = 0; int[,] idxC = { { 0, 0 }, { 0, 0 } }; for (y = 0, idx = 0; y < this.height - 2; y++) { int l = y % 2; //fila par o impar int l2 = (l == 0 ? 1 : 0); idx0 = y * this.stride; //índice a la fila actual idx1 = idx0 + this.stride; //índice a la siguiente for (x = 0; x < this.width - 1; x++, idx += 3) { int c = x % 2; //columna par o impar int c2 = (c == 0 ? 1 : 0); int[,] bidx = { { 0, 0 }, { 0, 0 } }; //índices a lo píxeles de la ventana bidx[0, 0] = idx0 + x * this.ColorPlanes; //sobra: ColorPlanes = 1 (imagen en grises) bidx[0, 1] = bidx[0, 0] + this.ColorPlanes; bidx[1, 0] = idx1 + x * this.ColorPlanes; bidx[1, 1] = bidx[1, 0] + this.ColorPlanes; //bSubMatrix contendrá la ventana de bayer bSubMatrix[0, 0] = bMatrix[idxBayerMatrix, l, c]; bSubMatrix[0, 1] = bMatrix[idxBayerMatrix, l, c2]; bSubMatrix[1, 0] = bMatrix[idxBayerMatrix, l2, c]; bSubMatrix[1, 1] = bMatrix[idxBayerMatrix, l2, c2]; //ahora a componer el color!! ... dependiendo del pixel donde estemos float[] C = { 0, 0, 0 }; float[] nC = { 0, 0, 0 }; for (int by = 0; by < 2; by++) for (int bx = 0; bx < 2; bx++) { C[bSubMatrix[by, bx]] += this.data[bidx[by, bx]]; //aquí l nC[bSubMatrix[by, bx]]++; } //compensación de la contribución de cada color en la ventana, nC[i] es el peso del canal i for (int ic = 0; ic < 3; ic++) C[ic] = C[ic] / nC[ic]; data2[idx] = C[0]; //B data2[idx + 1] = C[1]; //G data2[idx + 2] = C[2]; //R } idx += 3; } this.ColorPlanes = 3; this.stride = this.width * this.ColorPlanes; this.data = null; this.data = data2; } ----------------------------------------------------------------------------------------------- ----- Original Message ----- From: "Antonio Fraga" <ant...@ya...> To: "Lista de correo de desarrollo EQAlign" <eqa...@li...> Sent: Thursday, October 04, 2007 7:36 PM Subject: Re: [Eqalign-devel] Me está dando guerra la QHY Este tema del GDI es muy interesante!!, lo siento chicos, me incorporo al hilo en un par de horas, ahora sólo tuve tiempo de leer el correo pero es la hora del baño-cena-cuento-cama de Matías, el ritual de todos los días :-)) Sólo una cosa, hasta donde pude averiguar el GDI no permite guardar TIFF 16, en su día me hice con las librerías de FreeImage para eso; pero si, por ahora, lo que queremos es captarla como cámara guía, lo que tenemos que hacer es convertir el formato de profundidad de bit 16 a profundidad 8. Otra cosa más, la Luna es en color ¿no?, al recogerlo en un formato de 16bits grayscale, como debe ser, lo que vas a tener es una imagen RAW como dices, con la matriz de bayer bien clarita. Lo primero que hay que hacer es "debayerizarla", también tengo código para eso. Y otra cosa, en el proyecto hay un miniplanteamiento de una clase de tipo FloatImage, aunque sería más lento, si lo que se quiere es guardar la imagen en 16bits, se puede utilizar como "trampolín" al FreeImage. Es más lento porque el buffer de FreeImage es más óptimo, pero en ese formato (el de FloatImage) tengo diseñados algunos filtros: estadísticos (mediana/media/stddev) histogramas, curvas, rotaciones, remuestreos, desenfoques, unsharpmask, DDP,... aunque se puede utilizar FreeImage directamente (que también también implementa algunos tratamientos básicos en 32 bits) y dejar el proceso a un programa especializado... como debe ser. En fin, luego sigo con calma. ----- Original Message ----- From: "Andres del Pozo Prieto" <and...@gm...> To: "Lista de correo de desarrollo EQAlign" <eqa...@li...> Sent: Thursday, October 04, 2007 6:31 PM Subject: Re: [Eqalign-devel] Me está dando guerra la QHY Francisco José wrote: > Pues eso, hartito me tiene... os planteo otra duda, a ver, tengo este > código: > > // El buffer será de 2621440 bytes (16 bits por pixel, > // la cámara tiene 1310720 pixels) > PixelFormat format = PixelFormat.Format16bppGrayScale; > System.Drawing.Bitmap bmp = new > System.Drawing.Bitmap(1280, 1024, format); > System.Drawing.Imaging.BitmapData bmpData = > bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, > bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, format); > GETBUFFER(bmpData.Scan0,1310720); > bmp.UnlockBits(bmpData); > > Entiendo que en bmpData.Scan0 tengo el comienzo de la imagen RAW ¿y > ahora qué he de realizar para obtener la imagen? Si intento guardar o > fijarla a un control PictureBox me dice que el argumento es inválido > en una excepción en tiempo de ejecución, por ejemplo: > > bmp.Save(@"c:\test.bmp", ImageFormat.Bmp); Si no recuerdo mal el formato BMP no admite el formato de greyscale de 16bits. Puedes probar si te lo guarda en formato TIFF. > Ya mareado, y siendo honesto, he localizado en una web este código, > pero genera imágenes de 32bits RGB, logro guardar la imagen pero > claro, la cámara es monocromo y a 16: > > [DllImport("kernel32.dll")] > private static extern uint CopyMemory (IntPtr dest, IntPtr > Source, int Length); > > private Bitmap Bitmap32FromUnmanagedArray1(IntPtr image, int > width, int height) > { > Bitmap bmp = new Bitmap(width, height, > PixelFormat.Format32bppRgb); > > BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, > bmp.Width, bmp.Height), > ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); > > IntPtr dest = bmData.Scan0; > IntPtr source = image; > int len = width*4; > > if ( bmData.Stride == len ) > { > CopyMemory(dest, source, width*height*4); > } > else > { > for( int y = 0; y < bmp.Height; y++ ) > { > CopyMemory(dest, source, len); > > source = new IntPtr(source.ToInt32() + len); > dest = new IntPtr(dest.ToInt32() + bmData.Stride); > } > } > > > bmp.UnlockBits(bmData); > > return bmp; > } > > Cambiando Format32bppArgb por Format16bppGrayScale me da error de > acceso a memoria, soy torpe, ¿qué hago mal? Además de cambiar el pixelformat a 16bits tienes que cambiar los dos factores 4 por 2!!! Saludos, Andrés. ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Eqalign-devel mailing list Eqa...@li... https://lists.sourceforge.net/lists/listinfo/eqalign-devel ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Eqalign-devel mailing list Eqa...@li... https://lists.sourceforge.net/lists/listinfo/eqalign-devel |