示例#1
0
        protected void TestConvertLDR2HDR( System.IO.FileInfo[] _LDRImageFileNames, bool _responseCurveOnly, bool _RAW )
        {
            try {

                // Load the LDR images
                List< ImageFile >	LDRImages = new List< ImageFile >();
                foreach ( System.IO.FileInfo LDRImageFileName in _LDRImageFileNames )
                    LDRImages.Add( new ImageFile( LDRImageFileName ) );

                // Retrieve the shutter speeds
                List< float >	shutterSpeeds = new List< float >();
                foreach ( ImageFile LDRImage in LDRImages ) {
                    shutterSpeeds.Add( LDRImage.Metadata.ExposureTime );
                }

                // Retrieve filter type
                Bitmap.FILTER_TYPE	filterType = Bitmap.FILTER_TYPE.NONE;
                if ( radioButtonFilterNone.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.NONE;
                } else if ( radioButtonFilterGaussian.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.SMOOTHING_GAUSSIAN;
                } else if ( radioButtonFilterGaussian2Pass.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.SMOOTHING_GAUSSIAN_2_PASSES;
                } else if ( radioButtonFilterTent.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.SMOOTHING_TENT;
                } else if ( radioButtonFilterCurveFitting.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.GAUSSIAN_PLUS_CURVE_FITTING;
                }

            // Check EXR save is working!
            // ImageFile	pipo = new ImageFile();
            // 			pipo.ConvertFrom( LDRImages[0], ImageFile.PIXEL_FORMAT.RGB32F );
            // pipo.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_DEFAULT );

            // Check bitmap->tone mapped image file is working
            // {
            // 	Bitmap	tempBitmap = new Bitmap();
            // 	List< float >	responseCurve = new List< float >( 256 );
            // 	for ( int i=0; i < 256; i++ )
            // 		responseCurve.Add( (float) (Math.Log( (1+i) / 256.0 ) / Math.Log(2)) );
            // 	tempBitmap.LDR2HDR( new ImageFile[] { LDRImages[4] }, new float[] { 1.0f }, responseCurve, 1.0f );
            //
            // 	ImageFile	tempHDR = new ImageFile();
            // 	tempBitmap.ToImageFile( tempHDR, new ColorProfile( ColorProfile.STANDARD_PROFILE.LINEAR ) );
            //
            // 	ImageFile	tempToneMappedHDR = new ImageFile();
            // 	tempToneMappedHDR.ToneMapFrom( tempHDR,( float3 _HDRColor, ref float3 _LDRColor ) => {
            // 		// Just do gamma un-correction, don't care about actual HDR range...
            // 		_LDRColor.x = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.x ), 1.0f / 2.2f );	// Here we need to clamp negative values that we sometimes get in EXR format
            // 		_LDRColor.y = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.y ), 1.0f / 2.2f );	//  (must be coming from the log encoding I suppose)
            // 		_LDRColor.z = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.z ), 1.0f / 2.2f );
            // 	} );
            //
            // 	panel1.Bitmap = tempToneMappedHDR.AsBitmap;
            // 	return;
            // }

                //////////////////////////////////////////////////////////////////////////////////////////////
                // Build the HDR device-independent bitmap
            //				uint bitsPerPixel = _RAW ? 12U : 8U;
            uint	bitsPerPixel = _RAW ? 8U : 8U;
            float	quality = _RAW ? 3.0f : 3.0f;

                Bitmap.HDRParms	parms = new Bitmap.HDRParms() {
                    _inputBitsPerComponent = bitsPerPixel,
                    _luminanceFactor = 1.0f,
                    _curveSmoothnessConstraint = 1.0f,
                    _quality = quality,
                    _responseCurveFilterType = filterType
                };

                ImageUtility.Bitmap	HDRImage = new ImageUtility.Bitmap();

            //				HDRImage.LDR2HDR( LDRImages.ToArray(), shutterSpeeds.ToArray(), parms );

                // Compute response curve
                List< float >	responseCurve = new List< float >();
                Bitmap.ComputeCameraResponseCurve( LDRImages.ToArray(), shutterSpeeds.ToArray(), parms._inputBitsPerComponent, parms._curveSmoothnessConstraint, parms._quality, responseCurve );

                // Filter
                List< float >	responseCurve_filtered = new List< float >();
            //				Bitmap.FilterCameraResponseCurve( responseCurve, responseCurve_filtered, Bitmap.FILTER_TYPE.CURVE_FITTING );
                Bitmap.FilterCameraResponseCurve( responseCurve, responseCurve_filtered, filterType );

            // 				using ( System.IO.FileStream S = new System.IO.FileInfo( "../../responseCurve3.float" ).Create() )
            // 					using ( System.IO.BinaryWriter W = new System.IO.BinaryWriter( S ) ) {
            // 						for ( int i=0; i < 256; i++ )
            // 							W.Write( responseCurve[i] );
            // 					}

                // Write info
                string		info = "Exposures:\r\n";
                foreach ( float shutterSpeed in shutterSpeeds )
                    info += " " + shutterSpeed + "s + ";
                info += "\r\nLog2 exposures (EV):\r\n";
                foreach ( float shutterSpeed in shutterSpeeds )
                    info += " " + (float) (Math.Log( shutterSpeed ) / Math.Log(2)) + "EV + ";
                info += "\r\n\r\n";

                if ( _responseCurveOnly ) {
                    //////////////////////////////////////////////////////////////////////////////////////////////
                    // Render the response curve as a graph
             					ImageFile	tempCurveBitmap = new ImageFile( 1024, 768, ImageFile.PIXEL_FORMAT.RGB8, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) );

                    int			responseCurveSizeMax = responseCurve.Count-1;

                    float2		rangeX = new float2( 0, responseCurveSizeMax+1 );
                    float2		rangeY = new float2( 0, 500 );
                    tempCurveBitmap.Clear( new float4( 1, 1, 1, 1 ) );
            //					tempCurveBitmap.PlotGraphAutoRangeY( red, rangeX, ref rangeY, ( float x ) => {
                    tempCurveBitmap.PlotGraph( red, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve[i0];
                        float	g1 = responseCurve[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    } );
                    tempCurveBitmap.PlotGraph( blue, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve_filtered[i0];
                        float	g1 = responseCurve_filtered[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    } );
            //					tempCurveBitmap.PlotAxes( black, rangeX, rangeY, 8, 2 );

                    info += "• Linear range Y = [" + rangeY.x + ", " + rangeY.y + "]\r\n";

                    rangeY = new float2( -4, 4 );
                    tempCurveBitmap.PlotLogGraphAutoRangeY( black, rangeX, ref rangeY, ( float x ) => {
            //					tempCurveBitmap.PlotLogGraph( black, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve[i0];
                        float	g1 = responseCurve[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    }, -1.0f, 2.0f );
                    tempCurveBitmap.PlotLogGraph( blue, rangeX, rangeY, ( float x ) => {
            //					tempCurveBitmap.PlotLogGraph( black, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve_filtered[i0];
                        float	g1 = responseCurve_filtered[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    }, -1.0f, 2.0f );
                    tempCurveBitmap.PlotLogAxes( black, rangeX, rangeY, -16, 2 );

                    info += "• Log2 range Y = [" + rangeY.x + ", " + rangeY.y + "]\r\n";

             					panelOutputHDR.Bitmap = tempCurveBitmap.AsBitmap;

                } else {
                    //////////////////////////////////////////////////////////////////////////////////////////////
                    // Recompose the HDR image
                    HDRImage.LDR2HDR( LDRImages.ToArray(), shutterSpeeds.ToArray(), responseCurve_filtered, 1.0f );

                    // Display as a tone-mapped bitmap
                    ImageFile	tempHDR = new ImageFile();
                    HDRImage.ToImageFile( tempHDR, new ColorProfile( ColorProfile.STANDARD_PROFILE.LINEAR ) );

                    if ( _RAW ) {
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromRAW\Result.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_DEFAULT );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromRAW\Result_B44LC.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_B44 | ImageFile.SAVE_FLAGS.SF_EXR_LC );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromRAW\Result_noLZW.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_NONE );
                    } else {
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_DEFAULT );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result_B44LC.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_B44 | ImageFile.SAVE_FLAGS.SF_EXR_LC );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result_noLZW.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_NONE );
                    }

                    ImageFile	tempToneMappedHDR = new ImageFile();
                    tempToneMappedHDR.ToneMapFrom( tempHDR,( float3 _HDRColor, ref float3 _LDRColor ) => {
                        // Just do gamma un-correction, don't care about actual HDR range...
                        _LDRColor.x = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.x ), 1.0f / 2.2f );	// Here we need to clamp negative values that we sometimes get in EXR format
                        _LDRColor.y = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.y ), 1.0f / 2.2f );	//  (must be coming from the log encoding I suppose)
                        _LDRColor.z = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.z ), 1.0f / 2.2f );
                    } );

                    panelOutputHDR.Bitmap = tempToneMappedHDR.AsBitmap;
                }

                textBoxHDR.Text = info;

            } catch ( Exception _e ) {
                MessageBox.Show( "Error: " + _e.Message );

            // Show debug image
            // panelLoad.Bitmap = Bitmap.DEBUG.AsBitmap;
            }
        }