From: uknf@rzstud1.rz.uni-karlsruhe.de (Olaf Titz) Newsgroups: alt.sources,alt.graphics.pixutils,alt.binaries.pictures.utilities Subject: pgmhisteq - equalize the contrast in a portable graymap Followup-To: alt.sources.d Date: 12 Jul 1994 10:06:16 GMT Organization: Fachschaft math/inf, Uni Karlsruhe, FRG Lines: 230 Message-ID: <2vtpuo$e2@nz12.rz.uni-karlsruhe.de> NNTP-Posting-Host: rzstud1.rz.uni-karlsruhe.de Keywords: contrast enhancement, pbmplus Archive-name: pgmhisteq Submitted-by: Olaf Titz pgmhisteq - equalize the contrast in a portable graymap This program implements the "HistEq" function from the xv color editor for pgm files. For most pictures, it enhances the contrast noticeably. The effect is that after processing, for each x between 0 and 100, x percent of the image will have a brightness of at most x percent. The program needs the pbmplus libraries. Olaf # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' Xpgmhisteq - equalize the contrast in a portable graymap X XThis program implements the "HistEq" function from the xv color editor Xfor pgm files. For most pictures, it enhances the contrast noticeably. XThe effect is that after processing, for each x between 0 and 100, x Xpercent of the image will have a brightness of at most x percent. X XThe application I originally needed this for was processing of weather Ximages. Depending on the weather ;-) these vary greatly in their Xcontrast and overall brightness, so I need a means of "normalizing" Xthem (as opposed to contrast enhancement with pgmnorm taking fixed Xparameters). It gives a much better display especially when dithered Xon a b/w screen. Theoretically, in this case, exactly half of the Xpixels should be black and the other half white. X XThe program needs the libraries and headers from pbmplus. The actual Xcode is derived from pgmnorm by inserting the histogram algorithm X(looked up in xv). END_OF_FILE if test 945 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(348 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' XCC=cc XPBMPLUS=/usr/local/src/pbmplus XINCLUDE=-I$(PBMPLUS) -I$(PBMPLUS)/pbm -I$(PBMPLUS)/pgm XCFLAGS=-O XLDFLAGS=-s XLIB=-L/usr/local/lib X Xall: pgmhisteq X Xpgmhisteq: pgmhisteq.o X $(CC) $(LDFLAGS) $(LIB) -o pgmhisteq pgmhisteq.o -lpgm -lpbm X Xpgmhisteq.o: pgmhisteq.c X $(CC) $(CFLAGS) $(INCLUDE) -c pgmhisteq.c X Xclean: X rm -f core a.out pgmhisteq *.o *~ END_OF_FILE if test 348 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'pgmhisteq.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pgmhisteq.c'\" else echo shar: Extracting \"'pgmhisteq.c'\" \(2157 characters\) sed "s/^X//" >'pgmhisteq.c' <<'END_OF_FILE' X/* pgmhisteq.c - read a portable graymap and equalize the contrast X** X** Copyright (C) 1989, 1991 by Jef Poskanzer. X** (C) 1994 by Olaf Titz. X** X** Permission to use, copy, modify, and distribute this software and its X** documentation for any purpose and without fee is hereby granted, provided X** that the above copyright notice appear in all copies and that both that X** copyright notice and this permission notice appear in supporting X** documentation. This software is provided "as is" without express or X** implied warranty. X*/ X X#include "pgm.h" X Xstatic int hist[PGM_MAXMAXVAL+1], histeq[PGM_MAXMAXVAL+1]; X Xvoid Xmain( argc, argv ) Xint argc; Xchar* argv[]; X { X FILE* ifp; X gray maxval; X gray** grays; X register gray* gP; X int argn, rows, cols, row; X register int col; X int i, size, total, topbin, maxv; X int rminv, rmaxv; X char* usage = "[pgmfile]"; X X pgm_init( &argc, argv ); X X argn = 1; X if ( argn < argc ) X { X ifp = pm_openr( argv[argn] ); X ++argn; X } X else X ifp = stdin; X X if ( argn != argc ) X pm_usage( usage ); X X { X grays = pgm_readpgm( ifp, &cols, &rows, &maxval ); X pm_close( ifp ); X X /* Build histogram. */ X for ( i = 0; i <= maxval; ++i ) X hist[i] = histeq[i] = 0; X for ( row = 0; row < rows; ++row ) X for ( col = 0, gP = grays[row]; col < cols; ++col, ++gP ) X ++hist[*gP]; X size = rows * cols; X for (i=0; i<256 && !hist[i]; i++); X rminv = i; X for (i=255; i>0 && !hist[i]; i--); X rmaxv = i; X X /* Normalize. */ X total = topbin = 0; X for (i=0; i<256; i++) { X histeq[i] = (total * 255) / size; X if (hist[i]) topbin = i; X total += hist[i]; X } X X /* stretch range, as histeq[255] is probably *not* equal to 255 */ X maxv = (histeq[topbin]) ? histeq[topbin] : 255; /* avoid div by 0 */ X for (i=0; i<256; i++) X histeq[i] = (histeq[i] * 255) / maxv; X X /* Output. */ X pgm_writepgminit( stdout, cols, rows, maxval, 0 ); X for ( row = 0; row < rows; ++row ) X { X for ( col = 0, gP = grays[row]; col < cols; ++col, ++gP ) X *gP = histeq[*gP]; X pgm_writepgmrow( stdout, grays[row], cols, maxval, 0 ); X } X } X X pm_close( stdout ); X exit( 0 ); X } END_OF_FILE if test 2157 -ne `wc -c <'pgmhisteq.c'`; then echo shar: \"'pgmhisteq.c'\" unpacked with wrong size! fi # end of 'pgmhisteq.c' fi if test -f 'pgmhisteq.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pgmhisteq.1'\" else echo shar: Extracting \"'pgmhisteq.1'\" \(1257 characters\) sed "s/^X//" >'pgmhisteq.1' <<'END_OF_FILE' X.TH pgmhisteq 1 "9 July 1994" X.IX pgmhisteq X.SH NAME Xpgmhisteq - equalize the contrast in a portable graymap X.SH SYNOPSIS X.B pgmhisteq X.RI [ pgmfile ] X.SH DESCRIPTION XReads a portable graymap as input. XNormalizes the contrast by forcing the lightest pixels to white, the X.IX "contrast normalization" Xdarkest pixels to black, and rescaling the values in between in a way Xthat the distribution of intensity values in the output is uniform; Xand produces a portable graymap as output. X XThe output has the following property: For any value of x between 0 Xand 100, exactly x percent of the whole picture have an intensity of Xat most x percent. X.SH "SEE ALSO" Xpgmhist(1), pgmnorm(1), pgm(5), xv(1) X.SH AUTHOR XIdea taken from xv(1) by John Bradley. XActual code derived from pgmnorm(1) by Jef Poskanzer. XHacked together by Olaf Titz. X XCopyright (C) 1989 by Jef Poskanzer. X.\" Permission to use, copy, modify, and distribute this software and its X.\" documentation for any purpose and without fee is hereby granted, provided X.\" that the above copyright notice appear in all copies and that both that X.\" copyright notice and this permission notice appear in supporting X.\" documentation. This software is provided "as is" without express or X.\" implied warranty. END_OF_FILE if test 1257 -ne `wc -c <'pgmhisteq.1'`; then echo shar: \"'pgmhisteq.1'\" unpacked with wrong size! fi # end of 'pgmhisteq.1' fi echo shar: End of shell archive. exit 0 -- ___ olaf@bigred.ka.sub.org - uknf@rz.uni-karlsruhe.de __ o click __/<_ also: s_titz@ira.uka.de - uknf@dkauni2.bitnet - praetorius@irc _)>(_)_________ "now i find that most of the time love's not enough in itself"