- Update from 1.3 to 1.4

- Add stage support
- Convert LIB_DEPENDS to new syntax

PR:		ports/191183
Submitted by:	ii@any.com.ru
This commit is contained in:
Danilo Egea Gondolfo 2014-06-20 00:40:44 +00:00
parent 2c660b5a6e
commit 226c7a8e89
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=358483
9 changed files with 141 additions and 356 deletions

View file

@ -2,10 +2,10 @@
# $FreeBSD$
PORTNAME= pfscalibration
PORTVERSION= 1.3
PORTREVISION= 4
PORTVERSION= 1.4
CATEGORIES= graphics
MASTER_SITES= SF/pfstools/${PORTNAME}/${PORTVERSION}
MASTER_SITES= SF
MASTER_SITE_SUBDIR= pfstools/${PORTNAME}/${PORTVERSION}
MAINTAINER= ii@any.com.ru
COMMENT= Photometric calibration of cameras and recovery HDR images from the set of LDR exposures
@ -15,18 +15,16 @@ PFS_LDFLAGS= -L${LOCALBASE}/lib
USES= gmake pkgconfig shebangfix perl5
GNU_CONFIGURE= yes
CPPFLAGS+= ${PFS_CPPFLAGS}
LDFLAGS+= ${PFS_LDFLAGS}
CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
CONFIGURE_ENV= CPPFLAGS="${PFS_CPPFLAGS}" \
LDFLAGS="${PFS_LDFLAGS}"
LIB_DEPENDS= pfs-1.2:${PORTSDIR}/graphics/pfstools
USE_PERL5= run
MAN1= jpeg2hdrgen.1 \
dcraw2hdrgen.1 \
pfsinhdrgen.1 \
pfshdrcalibrate.1
SHEBANG_FILES= src/dcraw2hdrgen src/jpeg2hdrgen
SHEBANG_FILES= src/dcraw2hdrgen src/jpeg2hdrgen src/pfsinhdrgen
bash_CMD= ${SH}
NO_STAGE= yes
LIB_DEPENDS= libpfs-1.2.so:${PORTSDIR}/graphics/pfstools
.include <bsd.port.mk>

View file

@ -1,2 +1,2 @@
SHA256 (pfscalibration-1.3.tar.gz) = 4ced5e1ff45a9e3a02592b002c008c2c974b9d80762198e71e678e4c16e1b754
SIZE (pfscalibration-1.3.tar.gz) = 306650
SHA256 (pfscalibration-1.4.tar.gz) = 81982620c6dfd1d790e83f083e8740bfe1f34d25508054b931353d5de671db9e
SIZE (pfscalibration-1.4.tar.gz) = 338786

View file

@ -0,0 +1,11 @@
--- configure.orig 2008-08-21 22:57:21.000000000 +0000
+++ configure 2014-06-18 15:27:53.728960364 +0000
@@ -19337,7 +19337,7 @@
-CXXFLAGS="-O3 -funroll-loops -fstrength-reduce -fschedule-insns2 -felide-constructors -frerun-loop-opt -fexceptions -fno-strict-aliasing -fexpensive-optimizations -ffast-math -pipe"
+CXXFLAGS="-O3 -funroll-loops -fstrength-reduce -felide-constructors -fexceptions -fno-strict-aliasing -fexpensive-optimizations -ffast-math -pipe"

View file

@ -1,6 +1,6 @@
--- src/jpeg2hdrgen.orig Wed Aug 23 07:25:58 2006
+++ src/jpeg2hdrgen Thu Jun 21 14:34:33 2007
@@ -28,18 +28,25 @@
--- src/jpeg2hdrgen.orig 2006-08-22 18:34:04.000000000 +0000
+++ src/jpeg2hdrgen 2014-06-18 15:27:14.288956550 +0000
@@ -28,53 +28,105 @@
export LC_ALL
@ -11,86 +11,125 @@
- 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
- exit 1;
-fi
-
-#Note: Double backslash MUST be put in front of each $ sign
-AWK_PROGRAM=`cat <<EOF
+AWK_PROGRAM='
+AWK_PROGRAM_COMMON='
BEGIN {
exposure="";
aperture="";
@@ -58,23 +65,49 @@
}
END {
- if( aperture=="" )
+ if (aperture=="")
aperture=1;
- if( iso_speed=="" )
+ if (iso_speed=="")
iso_speed=100;
- if( exposure=="" )
+ if (exposure=="")
printf("not recognized exif header!\n");
else
print exposure " " aperture " " iso_speed " 0";
}
+'
+## jhead output
+AWK_PROGRAM_JHEAD='
/^Exposure time: ([0-9]*\.[0-9]) */ {
- exposure = 1/\\$3;
+ exposure = 1/$3;
+ next;
}
-
/^Aperture *: f\/([0-9]*\.[0-9]*)/ {
- aperture = substr(\\$3,3);
+ aperture = substr($3,3);
+ next;
}
-
/^ISO equiv. *: ([0-9]*\.?[0-9]*)/ {
- iso_speed = \\$4;
+ iso_speed = $4;
}
-EOF`
+ next;
+}'
+
+## exif output
+AWK_PROGRAM_EXIF='
+/^Exposure Time *\|.+ sec\./ {
+ if (split(substr($3,2),a,"/") == 2)
+ exposure = a[2];
+ else
+ exposure = 1/a[1];
+}
+ next;
}
+/^FNumber *\|f\/.+/ {
+ aperture = substr($2,4);
+ aperture = substr($2,4);
+ next;
+}
+/^ISO Speed Ratings *\|.+/ {
+ iso_speed = substr($4,2);
+ iso_speed = substr($4,2);
+ next;
+}'
+
+## exiv2 output
+AWK_PROGRAM_EXIV2='
+/^ExposureTime *.+/ {
+ if (split($2,a,"/") == 2)
+ exposure = a[2]/a[1];
+ next;
+}
+/^FNumber *.+/ {
+ if (split($2,a,"/") == 2)
+ aperture = a[1]/a[2];
+ next;
+}
+/^ISOSpeedRatings *.+/ {
+ iso_speed = $2;
+ next;
+}'
+
+JHEAD='jhead' # program for extracting exif info from jpegs
+EXIV2='exiv2' # another one
+EXIF='exif' # and one more
+
+if which ${JHEAD} >/dev/null
+then
+ CMD="$(which ${JHEAD})"
+ AWK_PROGRAM="${AWK_PROGRAM_COMMON}${AWK_PROGRAM_JHEAD}"
+elif which ${EXIV2} >/dev/null
+then
+ CMD="$(which ${EXIV2}) -P nv pr"
+ AWK_PROGRAM="${AWK_PROGRAM_COMMON}${AWK_PROGRAM_EXIV2}"
+elif which ${EXIF} >/dev/null
+then
+ CMD="$(which ${EXIF})"
+ AWK_PROGRAM="${AWK_PROGRAM_COMMON}${AWK_PROGRAM_EXIF}"
+else
+ cat <<MSG
+One of the following commands are required to run this script:
+ '${JHEAD}' - stand-alone program (http://www.sentex.net/~mwandel/jhead/)
+ '${EXIV2}' - part of exiv2 project (http://www.exiv2.org/)
+ '${EXIF}' - part of libexif project (http://sf.net/projects/libexif/)
+MSG
+ exit 1;
+fi
-EOF`
-
-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
-done
+done

View file

@ -1,99 +1,22 @@
--- 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 @@
--- src/pfshdrcalibrate.cpp.orig 2007-03-28 13:29:43.000000000 +0000
+++ src/pfshdrcalibrate.cpp 2014-06-18 15:27:14.288956550 +0000
@@ -126,7 +126,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);
- int c = getopt_long (argc, argv, "hvYFc:g:r:f:s:m:b:p:x", cmdLineOptions, &optionIndex);
+ int c = getopt_long (argc, argv, "hvYFc:g:r:f:s:m:b:p:xS: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
@@ -192,7 +192,9 @@
break;
case 'p':
mitsunaga_sample_no = (unsigned long)atoll(optarg);
- if( opt_bpp<10 || opt_bpp>=(1 << 31))
+ if( mitsunaga_sample_no<10 )
+ throw pfs::Exception("too few samples");
+ if( mitsunaga_sample_no>=(1 << 31) )
throw pfs::Exception("too many samples");
break;
case 'A': // max response

View file

@ -0,0 +1,10 @@
--- src/responses.cpp.orig 2006-09-13 14:27:06.000000000 +0000
+++ src/responses.cpp 2014-06-18 15:27:14.298952630 +0000
@@ -63,6 +63,7 @@
{
float mid = Mmin + (Mmax-Mmin)/2.0f - 0.5f;
float mid2 = (mid-Mmin) * (mid-Mmin);
+ std::cerr << "Mmin: " << Mmin << "; mid: " << mid << "; Mmax: " << Mmax << "; M: " << M << "; sigma: " << sigma << std::endl;
for( int m=0 ; m<M ; m++ )
if( m<Mmin || m>Mmax )
w[m] = 0.0f;

View file

@ -1,177 +0,0 @@
--- 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;
}

View file

@ -1,24 +0,0 @@
--- 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 );

View file

@ -1,4 +1,9 @@
bin/pfshdrcalibrate
bin/jpeg2hdrgen
bin/dcraw2hdrgen
bin/jpeg2hdrgen
bin/pfshdrcalibrate
bin/pfsinhdrgen
bin/pfsmergehdr
man/man1/jpeg2hdrgen.1.gz
man/man1/dcraw2hdrgen.1.gz
man/man1/pfsinhdrgen.1.gz
man/man1/pfshdrcalibrate.1.gz