diff options
-rw-r--r-- | graphics/Makefile | 1 | ||||
-rw-r--r-- | graphics/pfscalibration/Makefile | 33 | ||||
-rw-r--r-- | graphics/pfscalibration/distinfo | 3 | ||||
-rw-r--r-- | graphics/pfscalibration/files/patch-src-jpeg2hdrgen | 96 | ||||
-rw-r--r-- | graphics/pfscalibration/files/patch-src-pfshdrcalibrate.cpp | 99 | ||||
-rw-r--r-- | graphics/pfscalibration/files/patch-src-robertson02.cpp | 177 | ||||
-rw-r--r-- | graphics/pfscalibration/files/patch-src-robertson02.h | 24 | ||||
-rw-r--r-- | graphics/pfscalibration/pkg-descr | 6 | ||||
-rw-r--r-- | graphics/pfscalibration/pkg-plist | 4 |
9 files changed, 443 insertions, 0 deletions
diff --git a/graphics/Makefile b/graphics/Makefile index 54895ad5d298..563eca1efefa 100644 --- a/graphics/Makefile +++ b/graphics/Makefile @@ -526,6 +526,7 @@ SUBDIR += pecl-qrencode SUBDIR += pecomato SUBDIR += peps + SUBDIR += pfscalibration SUBDIR += pfstmo SUBDIR += pfstools SUBDIR += pgperl diff --git a/graphics/pfscalibration/Makefile b/graphics/pfscalibration/Makefile new file mode 100644 index 000000000000..574a82eaab5f --- /dev/null +++ b/graphics/pfscalibration/Makefile @@ -0,0 +1,33 @@ +# New ports collection makefile for: pfscalibration +# Date created: Fri Jun 1 15:44:40 UTC 2007 +# Whom: argv[0] (Iouri V. Ivliev) +# +# $FreeBSD$ + +PORTNAME= pfscalibration +PORTVERSION= 1.3 +CATEGORIES= graphics +MASTER_SITES= SF +MASTER_SITE_SUBDIR= pfstools + +MAINTAINER= ii@any.com.ru +COMMENT= Photometric calibration of cameras and recovery HDR images from the set of LDR exposures + +PFS_CPPFLAGS= -I${LOCALBASE}/include +PFS_LDFLAGS= -L${LOCALBASE}/lib + +GNU_CONFIGURE= yes +CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL} +CONFIGURE_ENV= CPPFLAGS="${PFS_CPPFLAGS}" \ + LDFLAGS="${PFS_LDFLAGS}" +USE_GMAKE= yes +USE_PERL5= yes + +LIB_DEPENDS= pfs-1.2:${PORTSDIR}/graphics/pfstools + +MAN1= jpeg2hdrgen.1 \ + dcraw2hdrgen.1 \ + pfsinhdrgen.1 \ + pfshdrcalibrate.1 + +.include <bsd.port.mk> diff --git a/graphics/pfscalibration/distinfo b/graphics/pfscalibration/distinfo new file mode 100644 index 000000000000..418f00f649ba --- /dev/null +++ b/graphics/pfscalibration/distinfo @@ -0,0 +1,3 @@ +MD5 (pfscalibration-1.3.tar.gz) = 5a08ec634cf53b105f412a826a2c2451 +SHA256 (pfscalibration-1.3.tar.gz) = 4ced5e1ff45a9e3a02592b002c008c2c974b9d80762198e71e678e4c16e1b754 +SIZE (pfscalibration-1.3.tar.gz) = 306650 diff --git a/graphics/pfscalibration/files/patch-src-jpeg2hdrgen b/graphics/pfscalibration/files/patch-src-jpeg2hdrgen new file mode 100644 index 000000000000..603e22d7757d --- /dev/null +++ b/graphics/pfscalibration/files/patch-src-jpeg2hdrgen @@ -0,0 +1,96 @@ +--- src/jpeg2hdrgen.orig Wed Aug 23 07:25:58 2006 ++++ src/jpeg2hdrgen Thu Jun 21 14:34:33 2007 +@@ -28,18 +28,25 @@ + export LC_ALL + + +-JHEAD="jhead" # program for extracting exif info from jpegs +- +-TEST_JHEAD=`which jhead`; +-if [ "$TEST_JHEAD" = "" ]; then +- echo "Program 'jhead' is required to run this script." +- echo "Install appropriate software, for example from:" +- echo "http://www.sentex.net/~mwandel/jhead/" ++JHEAD='jhead' # program for extracting exif info from jpegs ++EXIF='exif' # another one ++EXIV2='exiv2' # and one more ++ ++CMD=`which ${JHEAD}` ++[ -n "${CMD}" ] || CMD=`which ${EXIF}` ++[ -n "${CMD}" ] || CMD=`which ${EXIV2}` ++if [ -z "${CMD}" ] ++then ++ cat <<MSG ++One of the following commands are required to run this script: ++ '${JHEAD}' - stand-alone program (http://www.sentex.net/~mwandel/jhead/) ++ '${EXIF}' - part of libexif project (http://sf.net/projects/libexif/) ++ '${EXIV2}' - part of exiv2 project (http://www.exiv2.org/) ++MSG + exit 1; + fi + +-#Note: Double backslash MUST be put in front of each $ sign +-AWK_PROGRAM=`cat <<EOF ++AWK_PROGRAM=' + BEGIN { + exposure=""; + aperture=""; +@@ -58,23 +65,49 @@ + print exposure " " aperture " " iso_speed " 0"; + } + ++## jhead output + /^Exposure time: ([0-9]*\.[0-9]) */ { +- exposure = 1/\\$3; ++ exposure = 1/$3; + } +- + /^Aperture *: f\/([0-9]*\.[0-9]*)/ { +- aperture = substr(\\$3,3); ++ aperture = substr($3,3); + } +- + /^ISO equiv. *: ([0-9]*\.?[0-9]*)/ { +- iso_speed = \\$4; ++ iso_speed = $4; + } + +-EOF` ++## exif output ++/^Exposure Time *\|.+ sec\./ { ++ if (split(substr($3,2),a,"/") == 2) ++ exposure = a[2]; ++ else ++ exposure = 1/a[1]; ++} ++/^FNumber *\|f\/.+/ { ++ aperture = substr($2,4); ++} ++/^ISO Speed Ratings *\|.+/ { ++ iso_speed = substr($4,2); ++} + +-while [ "$1" != "" ]; do +- EXPOSURE_INFO=`$JHEAD $1 | awk "$AWK_PROGRAM"` +- echo $1 $EXPOSURE_INFO ++## exiv2 output ++/^Exposure time *: .+ s/ { ++ if (split($4,a,"/") == 2) ++ exposure = a[2]; ++ else ++ exposure = 1/a[1]; ++} ++/^Aperture *: F.+/ { ++ aperture = substr($3,2); ++} ++/^ISO speed *: .+/ { ++ iso_speed = $4; ++} ++' + ++while [ ${#} -ne 0 ] ++do ++ printf "${1} " ++ ${CMD} "${1}" | awk "${AWK_PROGRAM}" + shift + done diff --git a/graphics/pfscalibration/files/patch-src-pfshdrcalibrate.cpp b/graphics/pfscalibration/files/patch-src-pfshdrcalibrate.cpp new file mode 100644 index 000000000000..54ea07a97975 --- /dev/null +++ b/graphics/pfscalibration/files/patch-src-pfshdrcalibrate.cpp @@ -0,0 +1,99 @@ +--- src/pfshdrcalibrate.cpp.orig Wed Aug 23 14:49:59 2006 ++++ src/pfshdrcalibrate.cpp Thu Jun 21 14:40:28 2007 +@@ -108,7 +108,7 @@ + { "help", no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { "luminance", no_argument, NULL, 'Y' }, +- { "fillin-response", no_argument, NULL, 'F' }, ++// { "fillin-response", no_argument, NULL, 'F' }, + { "calibration", required_argument, NULL, 'c' }, + { "gauss", required_argument, NULL, 'g' }, + { "max-response", required_argument, NULL, 'A' }, +@@ -123,7 +123,7 @@ + + int optionIndex = 0; + while( 1 ) { +- int c = getopt_long (argc, argv, "hvYFc:g:r:f:s:m:b:", cmdLineOptions, &optionIndex); ++ int c = getopt_long (argc, argv, "hvYFc:g:r:f:s:m:b:S:A:", cmdLineOptions, &optionIndex); + if( c == -1 ) break; + switch( c ) { + case 'h': +@@ -246,8 +246,8 @@ + throw pfs::Exception("calibration method not set or not supported"); + } + +- VERBOSE_STR << "interpolate missing parts of response: " +- << (opt_fillgaps ? "yes" : "no") << endl; ++// VERBOSE_STR << "interpolate missing parts of response: " ++// << (opt_fillgaps ? "yes" : "no") << endl; + + if( responseSaveFile!=NULL ) + VERBOSE_STR << "save response curve to a file (do not generate HDR image)" << endl; +@@ -434,6 +434,8 @@ + pfs::Channel *Xj, *Yj, *Zj; + frame->createXYZChannels( Xj, Yj, Zj ); + ++ // !!! this currently does more bad than good, relevant command line ++ // option is disabled + if( opt_fillgaps ) + { + if( opt_luminance ) +@@ -453,42 +455,50 @@ + } + + // calibration ++ long sp = 0; // saturated pixels + switch( opt_calibration ) + { + case NONE: + if( opt_luminance ) + { + VERBOSE_STR << "applying response to Y channel..." << endl; +- robertson02_applyResponse( Yj, imgsY, Iy, w, M); ++ sp = robertson02_applyResponse( Yj, imgsY, Iy, w, M); + } + else + { + VERBOSE_STR << "applying response to R channel..." << endl; +- robertson02_applyResponse( Xj, imgsR, Ir, w, M); ++ sp = robertson02_applyResponse( Xj, imgsR, Ir, w, M); + VERBOSE_STR << "applying response to G channel..." << endl; +- robertson02_applyResponse( Yj, imgsG, Ig, w, M); ++ sp += robertson02_applyResponse( Yj, imgsG, Ig, w, M); + VERBOSE_STR << "applying response to B channel..." << endl; +- robertson02_applyResponse( Zj, imgsB, Ib, w, M); ++ sp += robertson02_applyResponse( Zj, imgsB, Ib, w, M); ++ sp /= 3; + } + break; + case ROBERTSON: + if( opt_luminance ) + { + VERBOSE_STR << "recovering Y channel..." << endl; +- robertson02_getResponse( Yj, imgsY, Iy, w, M); ++ sp = robertson02_getResponse( Yj, imgsY, Iy, w, M); + } + else + { + VERBOSE_STR << "recovering R channel..." << endl; +- robertson02_getResponse( Xj, imgsR, Ir, w, M); ++ sp = robertson02_getResponse( Xj, imgsR, Ir, w, M); + VERBOSE_STR << "recovering G channel..." << endl; +- robertson02_getResponse( Yj, imgsG, Ig, w, M); ++ sp += robertson02_getResponse( Yj, imgsG, Ig, w, M); + VERBOSE_STR << "recovering B channel..." << endl; +- robertson02_getResponse( Zj, imgsB, Ib, w, M); ++ sp += robertson02_getResponse( Zj, imgsB, Ib, w, M); ++ sp /= 3; + } + break; + case DEBEVEC: + break; ++ } ++ if( sp>0 ) ++ { ++ float perc = ceilf(100.0f*sp/size); ++ VERBOSE_STR << "saturated pixels found in " << perc << "% of the image!" << endl; + } + + // save response curve to a given file diff --git a/graphics/pfscalibration/files/patch-src-robertson02.cpp b/graphics/pfscalibration/files/patch-src-robertson02.cpp new file mode 100644 index 000000000000..207fb461ae2c --- /dev/null +++ b/graphics/pfscalibration/files/patch-src-robertson02.cpp @@ -0,0 +1,177 @@ +--- src/robertson02.cpp.orig Thu Mar 16 12:22:46 2006 ++++ src/robertson02.cpp Thu Jun 21 14:34:34 2007 +@@ -50,7 +50,7 @@ + float normalizeI( float* I, int M ); + + +-void robertson02_applyResponse( pfs::Array2D* xj, const ExposureList &imgs, ++int robertson02_applyResponse( pfs::Array2D* xj, const ExposureList &imgs, + const float* I, const float* w, int M ) + { + // number of exposures +@@ -59,6 +59,58 @@ + // frame size + int width = xj->getCols(); + int height = xj->getRows(); ++ ++ // number of saturated pixels ++ int saturated_pixels = 0; ++ ++ // --- anti saturation: calculate trusted camera output range ++ int minM = 0; ++ for( int m=0 ; m<M ; m++ ) ++ if( w[m]>0 ) ++ { ++ minM = m; ++ break; ++ } ++ int maxM = M-1; ++ for( int m=M-1 ; m>=0 ; m-- ) ++ if( w[m]>0 ) ++ { ++ maxM = m; ++ break; ++ } ++ ++ // --- anti ghosting: for each image i, find images with ++ // the immediately higher and lower exposure times ++ int* i_lower = new int[N]; ++ int* i_upper = new int[N]; ++ for( int i=0 ; i<N ; i++ ) ++ { ++ i_lower[i]=-1; ++ i_upper[i]=-1; ++ float ti = imgs[i].ti; ++ float ti_upper = imgs[0].ti; ++ float ti_lower = imgs[0].ti; ++ ++ for( int j=0 ; j<N ; j++ ) ++ if( i!=j ) ++ { ++ if( imgs[j].ti>ti && imgs[j].ti<ti_upper ) ++ { ++ ti_upper=imgs[j].ti; ++ i_upper[i]=j; ++ } ++ if( imgs[j].ti<ti && imgs[j].ti>ti_lower ) ++ { ++ ti_lower=imgs[j].ti; ++ i_lower[i]=j; ++ } ++ } ++ if( i_lower[i]==-1 ) ++ i_lower[i]=i; ++ if( i_upper[i]==-1 ) ++ i_upper[i]=i; ++ } ++ + + // all pixels + for( int j=0 ; j<width*height ; j++ ) +@@ -66,36 +118,64 @@ + // all exposures for each pixel + float sum = 0.0f; + float div = 0.0f; ++ ++ float maxti = -1e6f; ++ float minti = +1e6f; ++ + for( int i=0 ; i<N ; i++ ) + { + int m = (int) (*imgs[i].yi)(j); + float ti = imgs[i].ti; ++ ++ // --- anti saturation: observe minimum exposure time at which ++ // saturated value is present, and maximum exp time at which ++ // black value is present ++ if( m>maxM ) ++ minti = fminf(minti,ti); ++ if( m<minM ) ++ maxti = fmaxf(maxti,ti); ++ ++ // --- anti ghosting: monotonous increase in time should result ++ // in monotonous increase in intensity; make forward and ++ // backward check, ignore value if condition not satisfied ++ int m_lower = (int) (*imgs[i_lower[i]].yi)(j); ++ int m_upper = (int) (*imgs[i_upper[i]].yi)(j); ++ if( m_lower>m || m_upper<m) ++ continue; ++ + sum += w[m] * ti * I[m]; + div += w[m] * ti * ti; + } + +- // This part does not work so well +-// if( sum < 1e-4 ) { +-// // If there is not enough information to restore luminance +-// // (saturated pixels), do not use weighting function +-// for( int i=0 ; i<N ; i++ ) +-// { +-// int m = (int) (*imgs[i].yi)(j); +-// float ti = imgs[i].ti; +-// sum += ti * I[m]; +-// div += ti * ti; +-// } +-// } +- ++ // --- anti saturation: if a meaningful representation of pixel ++ // was not found, replace it with information from observed data ++ if( div==0.0f ) ++ saturated_pixels++; ++ if( div==0.0f && maxti>-1e6f ) ++ { ++ sum = I[minM]; ++ div = maxti; ++ } ++ if( div==0.0f && minti<+1e6f ) ++ { ++ sum = I[maxM]; ++ div = minti; ++ } ++ + if( div!=0.0f ) + (*xj)(j) = sum/div; + else + (*xj)(j) = 0.0f; + } ++ ++ delete[] i_lower; ++ delete[] i_upper; ++ ++ return saturated_pixels; + } + + +-void robertson02_getResponse( pfs::Array2D* xj, const ExposureList &imgs, ++int robertson02_getResponse( pfs::Array2D* xj, const ExposureList &imgs, + float* I, const float* w, int M ) + { + // number of exposures +@@ -105,6 +185,9 @@ + int width = imgs[0].yi->getCols(); + int height = imgs[0].yi->getRows(); + ++ // number of saturated pixels ++ int saturated_pixels = 0; ++ + // indexes + int i,j,m; + +@@ -160,7 +243,7 @@ + float middle_response = normalizeI( I, M ); + + // 3. Apply new response +- robertson02_applyResponse( xj, imgs, I, w, M ); ++ saturated_pixels = robertson02_applyResponse( xj, imgs, I, w, M ); + + // 4. Check stopping condition + float delta = 0.0f; +@@ -198,6 +281,8 @@ + delete[] Ip; + delete[] cardEm; + delete[] sum; ++ ++ return saturated_pixels; + } + + diff --git a/graphics/pfscalibration/files/patch-src-robertson02.h b/graphics/pfscalibration/files/patch-src-robertson02.h new file mode 100644 index 000000000000..aa05c9f74e3d --- /dev/null +++ b/graphics/pfscalibration/files/patch-src-robertson02.h @@ -0,0 +1,24 @@ +--- src/robertson02.h.orig Thu Mar 16 12:22:46 2006 ++++ src/robertson02.h Thu Jun 21 14:34:34 2007 +@@ -39,8 +39,9 @@ + * @param I [out] array to put response function + * @param w weights + * @param M max camera output (no of discrete steps) ++ * @return number of saturated pixels in the HDR image (0: all OK) + */ +-void robertson02_getResponse( pfs::Array2D* xj, const ExposureList &imgs, ++int robertson02_getResponse( pfs::Array2D* xj, const ExposureList &imgs, + float* I, const float* w, int M ); + + +@@ -53,8 +54,9 @@ + * @param I camera response function (array size of M) + * @param w weighting function for camera output values (array size of M) + * @param M number of camera output levels ++ * @return number of saturated pixels in the HDR image (0: all OK) + */ +-void robertson02_applyResponse( pfs::Array2D* xj, const ExposureList &imgs, ++int robertson02_applyResponse( pfs::Array2D* xj, const ExposureList &imgs, + const float* I, const float* w, int M ); + + diff --git a/graphics/pfscalibration/pkg-descr b/graphics/pfscalibration/pkg-descr new file mode 100644 index 000000000000..b2cef85a5b56 --- /dev/null +++ b/graphics/pfscalibration/pkg-descr @@ -0,0 +1,6 @@ +PFScalibration package provides an implementation of the Robertson +et al. 2003 method for the photometric calibration of cameras and +for the recovery of high dynamic range (HDR) images from the set +of low dynamic range (LDR) exposures. + +WWW: http://www.mpii.mpg.de/resources/hdr/calibration/pfs.html diff --git a/graphics/pfscalibration/pkg-plist b/graphics/pfscalibration/pkg-plist new file mode 100644 index 000000000000..05ad95a17e8a --- /dev/null +++ b/graphics/pfscalibration/pkg-plist @@ -0,0 +1,4 @@ +bin/pfshdrcalibrate +bin/jpeg2hdrgen +bin/dcraw2hdrgen +bin/pfsinhdrgen |