Beispiel #1
0
        /// <summary>
        /// Return a Bitmap created from the given CIELab color values
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public Bitmap GetBitmapFromCIELABImage( CIELab[] s, int width, int height )
        {
            // create map

            Bitmap b = new Bitmap( width, height, PixelFormat.Format32bppPArgb );

            // iterate pixels

            for( int y = 0 ; y < height ; y++ )
            {
                for( int x = 0 ; x < width ; x++ )
                {
                    // get CIE XYZ mapping for pixel and then convert this to CIE Lab

                    double CIE_X, CIE_Y, CIE_Z;

                    CIELab cie = s[ y * width + x ];

                    RgbaHls.CIELAB_2_CIEXYZ( cie.L, cie.a, cie.b, out CIE_X, out CIE_Y, out CIE_Z );

                    // convert back to RGB

                    Color c = RgbaHls.CIEXYZ_2_RGB( CIE_X, CIE_Y, CIE_Z );

                    // insert into bitmap

                    b.SetPixel( x, y, c );

                }
            }

            // return bitmap

            return b;
        }
Beispiel #2
0
        /// <summary>
        /// Return a Bitmap created from the given CIELab color values
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public Bitmap GetBitmapFromCIELABImage(CIELab[] s, int width, int height)
        {
            // create map

            Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppPArgb);

            // iterate pixels

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // get CIE XYZ mapping for pixel and then convert this to CIE Lab

                    double CIE_X, CIE_Y, CIE_Z;

                    CIELab cie = s[y * width + x];

                    RgbaHls.CIELAB_2_CIEXYZ(cie.L, cie.a, cie.b, out CIE_X, out CIE_Y, out CIE_Z);

                    // convert back to RGB

                    Color c = RgbaHls.CIEXYZ_2_RGB(CIE_X, CIE_Y, CIE_Z);

                    // insert into bitmap

                    b.SetPixel(x, y, c);
                }
            }

            // return bitmap

            return(b);
        }
Beispiel #3
0
        /// <summary>
        /// Return and a CIE Lab color mapping of the source image. Alpha is ignored. Also returns the
        /// min/max CIE L value found in the image.
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public CIELab[] GetCIELABImage(Bitmap source, out double minL, out double maxL)
        {
            // init L limits

            minL = double.MaxValue;

            maxL = double.MinValue;

            // create map

            CIELab[] map = new CIELab[source.Width * source.Height];

            // iterate pixels

            for (int y = 0; y < source.Height; y++)
            {
                for (int x = 0; x < source.Width; x++)
                {
                    // get CIE XYZ mapping for pixel and then convert this to CIE Lab

                    double CIE_X, CIE_Y, CIE_Z;

                    RgbaHls.RGB_2_CIEXYZ(source.GetPixel(x, y), out CIE_X, out CIE_Y, out CIE_Z);

                    double CIE_L, CIE_a, CIE_b;

                    RgbaHls.CIEXYZ_2_CIELAB(CIE_X, CIE_Y, CIE_Z, out CIE_L, out CIE_a, out CIE_b);

                    // insert into map

                    map[y * source.Width + x] = new CIELab(CIE_L, CIE_a, CIE_b);

                    // update L limits

                    minL = Math.Min(minL, CIE_L);

                    maxL = Math.Max(maxL, CIE_L);
                }
            }

            // return mapping

            return(map);
        }
Beispiel #4
0
        /// <summary>
        /// Create a new ( red eye removed ) image.
        /// </summary>
        /// <returns></returns>
        public Bitmap GetNewImage(CIELab[] cieMap, double minL, double maxL, Bitmap mask)
        {
            // create a set of target color which are the original CIE Lab colors set to gray scales by setting a* and b* to zero and stretching the L* to
            // the dynamic range of the image. This formula is used

            //
            //	L  =                 maxL
            //			 ----------------------------  * ( L - minL )
            //			         maxL - minL
            //
            //                      a = 0
            //					    b = 0
            //

            CIELab[] t = new CIELab[cieMap.Length];

            double r = maxL / (maxL - minL);

            for (int y = 0; y < mask.Height; y++)
            {
                for (int x = 0; x < mask.Width; x++)
                {
                    t[y * mask.Width + x] = new CIELab(r * (cieMap[y * mask.Width + x].L - minL), 0, 0);
                }
            }

            // now calculate a new CIE Lab color for pixel using:
            //
            // pixel = t[i,j] * mask[i,j] + ( cieMap[i,j] * ( 1 - mask[i,j] ) )
            //

            for (int j = 0; j < mask.Height; j++)
            {
                for (int i = 0; i < mask.Width; i++)
                {
                    // get normalized mask value for this pixel	( any of the RGB components will do, they should all be the same )

                    double m = (double)(mask.GetPixel(i, j).R) / 255.0;

                    // get original CIE Lab from ciemap

                    CIELab original = cieMap[j * mask.Width + i];

                    CIELab target = t[j * mask.Width + i];

                    // calculate new L* a* b* values using formula above

                    double L = target.L * m + original.L * (1 - m);

                    double a = target.a * m + original.a * (1 - m);

                    double b = target.b * m + original.b * (1 - m);

                    // reuse target array to hold new value for pixel ( in CIE Lab space )

                    t[j * mask.Width + i] = new CIELab(L, a, b);
                }
            }



            // return new image

            return(GetBitmapFromCIELABImage(t, mask.Width, mask.Height));
        }
Beispiel #5
0
        /// <summary>
        /// Create a new ( red eye removed ) image.
        /// </summary>
        /// <returns></returns>
        public Bitmap GetNewImage( CIELab[] cieMap, double minL, double maxL, Bitmap mask )
        {
            // create a set of target color which are the original CIE Lab colors set to gray scales by setting a* and b* to zero and stretching the L* to
            // the dynamic range of the image. This formula is used

            //
            //	L  =                 maxL
            //			 ----------------------------  * ( L - minL )
            //			         maxL - minL
            //
            //  					a = 0
            //					    b = 0
            //

            CIELab[] t = new CIELab[ cieMap.Length ];

            double r = maxL / ( maxL - minL );

            for( int y = 0 ; y < mask.Height ; y++ )
            {
                for( int x = 0 ; x < mask.Width ; x++ )
                {
                   t[ y * mask.Width + x ] = new CIELab( r * ( cieMap[ y * mask.Width + x ].L - minL ) , 0, 0 );
                }
            }

            // now calculate a new CIE Lab color for pixel using:
            //
            // pixel = t[i,j] * mask[i,j] + ( cieMap[i,j] * ( 1 - mask[i,j] ) )
            //

            for( int j = 0 ; j < mask.Height ; j++ )
            {
                for( int i = 0 ; i < mask.Width ; i++ )
                {

                    // get normalized mask value for this pixel	( any of the RGB components will do, they should all be the same )

                    double m = (double)(mask.GetPixel( i, j ).R) / 255.0;

                    // get original CIE Lab from ciemap

                    CIELab original = cieMap[ j * mask.Width + i ];

                    CIELab target = t[ j * mask.Width + i ];

                    // calculate new L* a* b* values using formula above

                    double L = target.L * m + original.L * ( 1 - m );

                    double a = target.a * m + original.a * ( 1 - m );

                    double b = target.b * m + original.b * ( 1 - m );

                    // reuse target array to hold new value for pixel ( in CIE Lab space )

                    t[ j * mask.Width + i ] = new CIELab( L, a, b );

                }
            }

            // return new image

            return GetBitmapFromCIELABImage( t, mask.Width, mask.Height );
        }
Beispiel #6
0
        /// <summary>
        /// Returns a bitmap of gray levels where the 'red-ness' of the original pixel determines the
        /// black/white value. Black pixels are farthest from red and white pixels are closest.
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public Bitmap GetMaskImage( CIELab[] cieMap, int width, int height )
        {
            // get chromaticty distance map and min/max chromaticty distances

            double minCD, maxCD;

            double[] cdMap = GetChromaticityDistanceMap( cieMap, width, height, out minCD, out maxCD );

            // create a black image of the same size

            Bitmap mask = ImageUtility.CreateImage( width, height, PixelFormat.Format32bppPArgb, Color.FromArgb(255,0,0,0) );

            // process each pixel

            for( int y = 0 ; y < height ; y++ )
            {
                for( int x = 0 ; x < width ; x++ )
                {

                    // Mask value =
                    //
                    //							    maxCD - chromaticty distance [x,y]
                    //				Round( 255 *  ------------------------------------- )
                    //								          maxCD - minCD
                    //

                    double temp = ( maxCD - cdMap[ y * width + x ] ) / ( maxCD - minCD );

                    int maskValue = (int)Math.Min( 255.0, Math.Max( 0.0, Math.Round( 255.0 * temp ) ) );

                    // set RGBA values

                    mask.SetPixel( x, y, Color.FromArgb( 255, maskValue, maskValue, maskValue ) );

                }
            }

            // return mask image

            return mask;
        }
Beispiel #7
0
        /// <summary>
        /// Return and a CIE Lab color mapping of the source image. Alpha is ignored. Also returns the
        /// min/max CIE L value found in the image.
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public CIELab[] GetCIELABImage( Bitmap source, out double minL, out double maxL )
        {
            // init L limits

            minL = double.MaxValue;

            maxL = double.MinValue;

            // create map

            CIELab[] map = new CIELab[ source.Width * source.Height ];

            // iterate pixels

            for( int y = 0 ; y < source.Height ; y++ )
            {
                for( int x = 0 ; x < source.Width ; x++ )
                {
                    // get CIE XYZ mapping for pixel and then convert this to CIE Lab

                    double CIE_X, CIE_Y, CIE_Z;

                    RgbaHls.RGB_2_CIEXYZ( source.GetPixel( x,y ), out CIE_X, out CIE_Y, out CIE_Z );

                    double CIE_L, CIE_a, CIE_b;

                    RgbaHls.CIEXYZ_2_CIELAB( CIE_X, CIE_Y, CIE_Z, out CIE_L, out CIE_a, out CIE_b );

                    // insert into map

                    map[ y * source.Width + x ] = new CIELab( CIE_L, CIE_a, CIE_b );

                    // update L limits

                    minL = Math.Min( minL, CIE_L );

                    maxL = Math.Max( maxL, CIE_L );

                }
            }

            // return mapping

            return map;
        }
Beispiel #8
0
        /// <summary>
        /// Given a CIELab array ( obtained with GetCIELABImage ) this calculate the chromaticity distance of
        /// each pixel fro the 'typical' red eye CIELAB color. Also returns the Min/Max chromaticity distances found
        /// </summary>
        /// <returns></returns>
        public double[] GetChromaticityDistanceMap( CIELab[] map, int width, int height, out double minDistance, out double maxDistance )
        {
            // initialize min/max

            minDistance = double.MaxValue;

            maxDistance = double.MinValue;

            // create return array

            double[] cdMap = new double[ width * height ];

            // iterate pixels

            for( int y = 0 ; y < height ; y++ )
            {
                for( int x = 0 ; x < width ; x++ )
                {
                    // get distance for this pixel

                    double c = RgbaHls.ChromaticityDistance( map[ y * width + x ].a, kA_REDEYE, map[ y * width + x ].b, kB_REDEYE );

                    // assign to map

                    cdMap[ y * width + x ] = c;

                    // update min/max

                    minDistance = Math.Min( minDistance, c );

                    maxDistance = Math.Max( maxDistance, c );

                }
            }

            // return chromaticty map

            return cdMap;
        }