Threshold filters (Rev Newsletter #48)

Wilhelm Sanke sanke at hrz.uni-kassel.de
Wed Feb 13 11:25:14 EST 2008


There is only sparse documentation about "imagedata" in Revolution. 
Without the more detailed information and sample stacks from the 
websites of other experienced members of this list I would probably 
never have got a start to learn and apply some of the possibilities of 
imagedata handling.

Therefore it is praiseworthy that he Revolution team now tries to 
provide us with more useful information in Newsletter #48 and introduce 
us to the "use of thresholding for image manipulation". They also apply 
modern "state-of-the-art" pedagogy, in so far as they bundle their 
example with kind of a joke for better learning. If such an approach 
isn't over-used it might indeed work.

My "Imagedata Toolkit" stack (last public version of May 2007

<http://www.sanke.org/Software/ImagedataToolkitPreview3.zip>)

among the more than 200 filters for manipulating imagedata already 
contains 7 filters using the threshold principle (see menu-button 
"thresholds").

I created another button in this stack adapting the script information 
in the newsletter to my environment to compare the new threshold filter.

First thing I noticed was that only 25% of an image is affected. This 
holds for all of the three script examples displayed in the newsletter. 
One important factor is missing in all these examples, which I leave to 
you to find out for yourselves (another instance of modern pedagogy).

I then downloaded the sample stack to have a look whether its scripts 
worked better, but for some reason I was unable to un-zip the stack on 
Windows, even after downloading it again. I transferred the archive to 
my Macbook and finally succeeded in extracting the stack using Stuffit 
Expander. Looking at the relevant script revealed that here the author 
of the stack had indeed added the missing factor.

Re-tranferring the unzipped stack back to Windows did not work first, 
until I found out  that Windows did not like the question-mark  as part 
of the stack name.
I removed the question-mark, and then  was able to get the stack onto my 
Windows computer, however, it was impossible to open it in Revolution.
Therefore I only extracted the necessary script from the stack on my 
Macbook and put it into my Imagedata-Toolkit stack on my Windows machine.

Now I was able to compare the threshold script with my own 7 threshold 
buttons. The solution found by the author - even disregarding the 
entertainment factor - was fine and its effects different, but somewhat 
similar to  those of my own buttons that use two or more thresholds.

However, I found the script to run much slower due to the many 
computations inside the nested repeat loops.-

======================
In the following, I use a step-by-step approach to show how the speed of 
the script execution could be improved. To do this I show only one of 
the thirteen script lines inside the loop that - concerning the 
definition of the imagedata chars - is identical to the other 12 lines.

"repeat with y = 1 to pHeight
    repeat with x = 1 to pWidth      
      put charToNum(char ((y - 1) * pWidth * 4) + ((x - 1)  * 4) + 2 of 
pImage) into tRed"

The script as it is takes 3500 milliseconds to execute for an image 
640x480 on my Windows computer.

Step 1: Remove the two "- 1" inside the loop and change the x and y 
start and end values accordingly;

new script:

"repeat with y = 0 to pHeight - 1
    repeat with x = 0 to pWidth - 1     
      put charToNum(char (y * pWidth * 4) + (x  * 4) + 2 of pImage) into 
tRed"

Speed gain here is about 300 milliseconds (now 3219).

Step 2: Compute "pwidth * 4" outside the loops;

new script:

"put pwidth * 4 into tpwidth
repeat with y = 0 to pHeight - 1
    repeat with x = 0 to pWidth - 1     
      put charToNum(char (y * tpWidth) + (x  * 4) + 2 of pImage) into tRed"

Speed gain another 300 ms (now 2932).

Step 3: Combine y with tpwidth;

new script:

"put pwidth * 4 into tpwidth
repeat with y = 0 to pHeight - 1
 put y * tpwidth into typwidth
    repeat with x = 0 to pWidth - 1     
      put charToNum(char typWidth + (x  * 4) + 2 of pImage) into tRed"

Step 4: put "x*4" into tx;

new script:

"put pwidth * 4 into tpwidth
repeat with y = 0 to pHeight - 1
 put y * tpwidth into typwidth
    repeat with x = 0 to pWidth - 1
      put x * 4 into tx    
      put charToNum(char typWidth + tx + 2 of pImage) into tRed"

Overall speed gain from beginning: 1 second (now 2585)

Step 5: Combine typwidth and tx;

new script:

"put pwidth * 4 into tpwidth
repeat with y = 0 to pHeight - 1
 put y * tpwidth into typwidth
    repeat with x = 0 to pWidth - 1
      put x * 4 into tx  
      put typwidth + tx into tyx  
      put charToNum(char tyx + 2 of pImage) into tRed"

Speed gain: another 100 ms (now 2461)

Step 6: Remove the irrelevant line accessing the alpha value of the 
imagedata char, i.e.

remove line (this is the original form)
"put charToNum(char ((y - 1) * pWidth * 4) + ((x - 1)  * 4) + 1 of 
pImage) into tAlpha"

Speed gain: again 100 ms (now 2340).--

Overall speed gain is now 33% compared to the speed of the original script.-

==========================
    
As an additional script example - which is not among the 7 scripts in my 
Imagedata stack - I  tried to find a very simply structured script using 
"for each" (which is by the way - in this case - slower than a nested 
repeat loop), applying only one threshold, and using only the red value 
to create a black-and-white image:

"on mouseup
  answer "Select threshold to create the black-and-white image:" with  
"80"  or "100"  or "128" or "150" or "180"
  wait 3 milliseconds
  put it into threshold
  set the cursor to watch
  put the imageData of image x into iData
 
  put 0 into counter
  repeat for each char C in idata
    add 1 to counter
    if counter mod 4 = 2 then # the red pixel
      put chartonum(C)  into tC
      if tC > threshold then
        put 255 into tC
      else
        put 0 into tC
      end if
    end if
    put numtochar(tC) into char counter of idata
  end repeat
 
  set the imageData of image x  to iData
end mouseUp"

(Pay attention to possible line breaks of this script  in this post.)

I hope I have added some useful information and thus have supported the 
efforts of the Rev team to familiarize us with imagedata manipulation.

Regards,

Wilhelm Sanke
<http://www.sanke.org/MetaMedia>





More information about the use-livecode mailing list