Saturday, August 6, 2011

Retinex Image Processing Batch Script

Target platform: Windows OS (tested on Windows 7).

How would you like to turn a photo like this one:

From Blogger


Into a photo like this one:

From Blogger


AUTOMATICALLY??? (and in batch-loads at a time!!!)

In my previous post, I introduced the art and science of book scanning, and announced that I am going digital... painfully digital. In this post, I will present the reader with a simple, yet powerful batch script that (when setup as forthwith described) will clear up any lighting issues one may encounter when attempting to digitize that lovely collection of Shakespearean sonnets! Hooray! :)

Let's hope this is not much ado about nothing, Mr. W.H., eh? eh?

Step One: Create folders and files!



Create a new folder anywhere you like, and name in anything you wish. I called my folder ePress (and will subsequently refer to this folder as the root folder for this project).

Now, create a file within this root folder and name it: "retinex.bat" (sans quotes). Leave the file empty for now...

Next, create a folder within the root folder, and name it "bin" (sans quotes).

Within the "bin" folder, create another folder and name it "img" (you know by now, right?)

One last time (I swear) create a folder within the "img" folder, and name it "magick" (sic, and sans quotes).

Finally... you should now have the following structure:


root/retinex.bat
root/bin/img/magick



Step Two: Download ImageMagick Binaries (*.exe files)



Visit http://www.imagemagick.org and find the binary release for your operating system. Now, DO NOT download the installer... You will need the release that comes as a *.zip file, as it contains all of the individual executables that comprise the ImageMagick (TM) tool-set.

At the time of the post, the following was the direct link to the zip file: DOWNLOAD.

Once you have the zip file (sometimes called the "portable" version), extract all of the executables (and whatever other junk: www, etc...) to the "magick" folder you created in step one. All we are really concerned about here is obtaining the "convert.exe" program!

Step Three: Create some more folders...



Within the root folder (ePress, for me...) create a folder and name it "tmp" (sans quotes).

Next, within the "tmp" folder, create a folder and name it "retinex" (you get the idea)...

Go BACK to the ROOT folder now...

Within the root folder, create a folder and name it "output".

Within the "output" folder, create a folder and name it "retinex".

Phew! You should now have the following new structures:



root/tmp/retinex
root/output/retinex



Step Four: Paste batch code into "retinex.bat" file!



First off, let me say that this code IS NOT an original concept! In fact, I only adapted one of the many scripts available to perform retinex image processing... this particular script was a shell script from Fred's ImageMagick Scripts

Now, on with the show...

Paste the following code into the file (that you created earlier) called "retinex.bat":



@ECHO OFF
CLS
echo -- RETINEX (R) IMAGE PROCESSING --
echo SCRIPT BY: Sean A. Finucane
echo July 22, 2011
echo __________________________________
echo Adapted from:
echo Fred's ImageMagick Scripts,
echo Retinex Bash Script
echo ----------------------------------
REM RETINEX IMAGE PROCESSING (HSL)
SET tmpA="%~dp0tmp\retinex\retinex_A.mpc"
SET tmpB="%~dp0tmp\retinex\retinex_B.cache"
SET tmpH="%~dp0tmp\retinex\retinex_H.png"
SET tmpS="%~dp0tmp\retinex\retinex_S.png"
SET tmp0="%~dp0tmp\retinex\retinex_0.png"
SET tmp1="%~dp0tmp\retinex\retinex_1.png"
SET tmp2="%~dp0tmp\retinex\retinex_2.png"
SET tmp3="%~dp0tmp\retinex\retinex_3.png"
REM PATH TO OUTPUT FILE
FOR %%I IN (echo %1) DO SET outputname=%%~nI
SET outfile="%~dp0output\retinex\%outputname%.png"
REM PATH TO IMAGE MAGICK CONVERT.EXE
SET convert="%~dp0bin\img\magick\convert.exe"
REM LOGARITHM TO USE FOR RETINEX ALGORITHM
SET formula="log((u+1))"
REM
echo Output file will be: %outfile%
echo --------
REM
echo REPAGING... Please wait.
echo --------
%convert% -quiet -regard-warnings %1 +repage %tmpA%
REM HSL COLOR MODE PROCESSING
REM Save original
echo HSL COLOR MODE PROCESSING... Please wait.
echo --------
%convert% %tmpA% %tmp0%
REM Convert to HSL reusing $tmpA for Lightness
echo Convert to HSL... Please wait.
echo --------
%convert% %tmpA% -colorspace HSL -channel R -separate %tmpH%
%convert% %tmpA% -colorspace HSL -channel G -separate %tmpS%
%convert% %tmpA% -colorspace HSL -channel B -separate %tmpA%
REM PROCESS IMAGE
echo Processing Reflectance Images - Please Wait, this may take some time...
echo --------
REM Get three resolution sizes (in this case, default=5, 20, and 240
SET res1=5
SET res2=20
SET res3=240
REM Create reflectance images at each resolution size
echo STAGE 1:
echo --------
%convert% %tmpA% ( +clone -blur 0x%res1% ) -fx %formula% %tmp1%
echo --------
echo STAGE 2:
echo --------
%convert% %tmpA% ( +clone -blur 0x%res2% ) -fx %formula% %tmp2%
echo --------
echo STAGE 3:
echo --------
%convert% %tmpA% ( +clone -blur 0x%res3% ) -fx %formula% %tmp3%
echo --------
echo Finalizing... Please wait.
echo --------
REM Average results (normalize as log reduces range of values)
%convert% %tmp1% %tmp2% %tmp3% -evaluate-sequence mean -normalize %tmp1%
REM Convert back to RGB and OUTPUT!
%convert% %tmp0% -colorspace HSL %tmpH% -compose CopyRed -composite %tmpS% -compose CopyGreen -composite %tmp1% -compose CopyBlue -composite -colorspace RGB %outfile%



... and VOILA! You may now drag and drop any SINGLE image file into the "retinex.bat" file, and it will be subsequently processed. As I mentioned previously, the primary advantage of retinex processing is the ability to improve a WIDE variety of images AUTOMATICALLY (i.e. without the need to tweak settings). The primary disadvantage is that the process is really quite S.L.O.W.

But, if you create a file (name it whatever you wish, as long as it is in the same directory as "retinex.bat") and paste the following batch script code into it:




@ECHO OFF
SET batchProg=retinex.bat
SET curDirectory=%~dp0
:NEXT_ITER
IF [%1]==[] GOTO FINISH
REM OTHERWISE, WE SHOULD PERFORM THE DESIRED OPERATION
CALL "%curDirectory%%batchProg%" "%%~dp1%%~n1%%~x1"
REM SHIFT THE ARGUMENT VARIABLES (%1 = %2, etc...)
SHIFT
GOTO NEXT_ITER
:FINISH
PAUSE



... you will then be able to drag and drop whole groups of files into the above batch file AT ONE TIME! Hooray for batch processing! :)

My file was cryptically named "batch_retinex.bat"...

Thursday, August 4, 2011

Going Digital... Painfully digital.

There's nothing quite like spending countless hours of your life slaving over a flatbed scanner, and trudging through the ascii fields of neverendor in the digitaurus rexus hades galaxy. Uncool, to the n double factorial degree.

There is some hope, however, for us mere mortals who foolishly embark down the rabbit hole into the realm of pseudo-reality -the nether space which sits so seemingly innocuously between our world and the land of dreams, the space in which reality becomes coarse, and vaguely familiar. All who dare enter, beware. The hope, of which I previously spake, is that you are NOT ALONE! Alas! Thine misery is spread! :)

My personal experience with the daunting task of digitizing all records, papers, books, music, videos, etc... began very recently (July / August 2011). Armed with my flatbed scanner, and many over-priced textbooks, I set forth this simple goal: to digitize all of my school books by the end of the summer (the end of September). I soon realized that a flatbed scanner is a sub-prime tool when current human life-spans are factored into the efficiency calculations.

Slow to be discouraged (i.e. stupid, or maybe naive at best), I began researching the methods employed by intelligencia web-wide. Ahhhh.... the sticky inter-web catches much. My initial (very short) research session turned up little usable information. Ahhhh.... the power of keywords unknown. Ironically, the knowledge I was seeking popped up randomly on the front page of a web-site (that I had just come across) known as: http://www.hackaday.com/ . I love serendipity. And hackaday.com.

Hack-A-Day had featured the following website and book scanner design: http://www.diybookscanner.org/

Somehow, I never managed to search something as simple as "book scanner"... hmm..... although, my initial search was literally one google query regarding digitizing books... not scanning them... because that was what I was failing at, scanning them.

My next blog will delve into the devilish details of applying ScanTailor modifications to a scanned set of pages (using a camera, somewhat like the design that is referenced above) and using the ImageMagick (TM) "convert.exe" program to apply Retinex image processing to the scanned pages (like NASA does to its images).

Stay tuned! :)

Wednesday, March 9, 2011

JumpLoader and Yii :: Uploading Files with the Yii Framework

I will try my best to keep this article like an inverted pyramid of information... but with this first sentence, I've already blown it, haven't I? Oh well. Odds are that if you're reading this post, you are looking for some simple widget / component for your Yii based web application that will allow a user to upload files to the server. Never fear, the JumpLoader yii component is here! [http://www.yiiframework.com/extension/jumploader-java-uploader]

What can this JumpLoader component do for you? Simple: it can be easily integrated into your Yii application as an extension, added as a component, and then used as a widget in your application's view files. Yes, it really is that easy. You can simply follow the link provided above to learn more about downloading and installing the JumpLoader Java Loader extension for the Yii Framework).

Tuesday, March 1, 2011

To Hell With It All, and Back Again? Chapter 1: Genesis



We've all gone down the path at some point: the black, shadowy stretch of what is possible; the path which connects the imagined with the realized, the make-believe with reality; the path of which successful failures dare not speak, of which failed successes reminisce, and of which the few and the proud often brag. How should we know this path when it approaches us? Just look for the sign which says, "Glory and despair await all those who dare... and for the rest of you, there are cookies and sandwiches in the back."

Now, let's get down to business. I am writing all of this with the hope that it will lend some semblance of aid to the poor schmuck (like myself) who decides to tackle similar (if not identical) projects... plus, I really would like a record of what the hell I've done wrong, and (on occasion) what I've done right. The Lord knows that our failures are our greatest victories.

My current project involves the design, development, and implementation of a Gantt Chart Generator of a sort. This generator, of a sort, is to be built within the Yii web application framework. Currently, I have produced a "rapid prototype" (which translates as: "a heap of code shoe-stringed within a single class, with few specialized functions to speak of, all rolled up and covered in a papier-mache interface"). This prototype takes advantage of the available widget functionality of Yii... and, more specifically, inherits from an extension known as "Open Flash Chart 2 Widget". Essentially, I extended this widget (subsequent "OFC2Widget") to provide the specific Gantt Chart generator that I desired. Of course, there are issues (euphemism for errors) that need resolved, but the widget does produce a simple gantt chart.

The task at hand is to redesign the internal structure of this proto-widget.