Fast method for counting RGB values of an image

Visuals, audio, animation. Blended, not stirred. If LiveCode is part of your rich media production toolbox, this is the forum for you.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

TorstenHolmer
Posts: 57
Joined: Mon Oct 28, 2013 1:23 pm
Location: Dresden, Germany

Fast method for counting RGB values of an image

Post by TorstenHolmer » Wed Jun 19, 2019 5:43 pm

Hi,

my task is simple, I want to count the amount of RGB values of the pixels in an image: how often 201,10,10 occurs in the image etc.

I found a stack, which does it, but the method is extremely slow: an image with 500 x 500 pixels needs half an hour or longer.

Is there a quicker method for counting the RGB values?

Kind regards
Torsten

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Fast method for counting RGB values of an image

Post by FourthWorld » Wed Jun 19, 2019 6:56 pm

Post the code and we will optimize it.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

TorstenHolmer
Posts: 57
Joined: Mon Oct 28, 2013 1:23 pm
Location: Dresden, Germany

Re: Fast method for counting RGB values of an image

Post by TorstenHolmer » Wed Jun 19, 2019 7:40 pm

This is the code from a stack named: rgbValuesOfImage from Bernd Niggemann (as can be seen in the comment section):

# getting the unique RGB values of an image
# putting them into an array to filter for unique RGB
# taking the keys of the array which now contain the unique RGB values
# the content of the key of the array is the frequency of each unique RGB value
# frequencies are not use here, could easily be adapted

# Bernd Niggemann, October 2013

Code: Select all

on mouseUp
   put the imageData of image "kircheganzKlein.jpg" into tData
   put the width of image "kircheganzKlein.jpg" into tWidth
   put the height of image "kircheganzKlein.jpg" into tHeight
   put tWidth * tHeight into tNumberOfPixel
   put tNumberOfPixel * 4 into tNumberOfbytes
   -- step through the imageData and get the RGB values of each pixel
   repeat with i = 1 to tNumberOfbytes - 4 step 4
      put charToNum (char i +1  of tData) & "," & charToNum( char i+2 of tData) & "," & charToNum (char i + 3 of tData) into tRGB
      add 1 to tArray[tRGB] -- make the RGB value the key of an array and add the frequency of that unique RGB value
   end repeat
   put the keys of tArray into tAllRGB -- now in tAllRGB are the unique RGB values of the image as list
   sort tAllRGB numeric by item 1 of each & item 2 of each & item 3 of each -- we sort the list
   put tAllRGB into field "fResult"
end mouseUp
It seems to me, that is uses a very slow method, because the stacks from Hermann Hoch (which I found today, esp. ImageStatistics) are MUCH quicker.

Thanks in advance (I will have a look at Hermann's code now),

Cheers,
Torsten

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Fast method for counting RGB values of an image

Post by [-hh] » Wed Jun 19, 2019 8:14 pm

The (still slow) method of Bernd is one of the fastest you can have with LC Script.

Walking through and manipulating imageData becomes very fast by using Javascript methods (via a browser widget).

Sample stack "imageStatistics shows, using Javascript, the three marginal distributions of R,G, and B.
You want to have the frequencies of the 256ˆ3 = 16777216 RGB values.
This should be doable still fast for an image of medium screen size (1920x1080).

The display of that 3D distribution will also require some time and you will have to build bins(value categories). But LC Script is fast enough for that.
Or give a surface plot by using for example https://plot.ly/javascript/3d-surface-plots/
shiftLock happens

TorstenHolmer
Posts: 57
Joined: Mon Oct 28, 2013 1:23 pm
Location: Dresden, Germany

Re: Fast method for counting RGB values of an image

Post by TorstenHolmer » Wed Jun 19, 2019 8:46 pm

Hi, that's great to hear from you!

My images are PNG files. Can you help me to find the right javascripts and how to implement them?

The output should look like this:

124,22,37 12971
0,38,255 12649
182,255,0 10730
255,0,0 9264
0,0,0 7920
255,106,0 7008
255,133,133 2

Thanks in advance
Torsten

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Fast method for counting RGB values of an image

Post by [-hh] » Wed Jun 19, 2019 10:29 pm

LC Script needs a lot of time to convert the binary colors to numeric r,g,b-triples. This has to be done in Javascript for gaining speed. For the frequency counting via arrays is LC as fast as Javascript.

Added to the sample stack: (sorry, currently not available)
The output is (as usual in Statistics the primary sort item first): Frequency,R,G,B

You can put these frequency listing of all used (R,G,B)-triplets into the xˆ3 bins that result from a divison of each channel range 0-255 into x=4,8,16,32,64,128,256 channel bins.
When using less then 256 bins the lower value of the R-bin is reported instead of the original R-value, similar for G and B.

**** If you wish to have low/high ranges (0-127 and 128-255) simply add 2 to the "bins" menus.****

By building bins you can define color-categories such as "close to white", for example with 64 bins this could be the ranges combination given by the last bin of each of (R,G,B) = (252-255,252-255,252-255).
Last edited by [-hh] on Wed Dec 11, 2019 11:45 pm, edited 7 times in total.
shiftLock happens

TorstenHolmer
Posts: 57
Joined: Mon Oct 28, 2013 1:23 pm
Location: Dresden, Germany

Re: Fast method for counting RGB values of an image

Post by TorstenHolmer » Thu Jun 20, 2019 10:55 am

Thanks a lot!!!
:D
Cheers,
Torsten

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Fast method for counting RGB values of an image

Post by [-hh] » Fri Jun 21, 2019 10:58 am

Please update:
Download "ImageStatistics_v165" from "Sample Stacks" or using http://livecodeshare.runrev.com/stack/882/

[Version 160 had an error in the javascript for listing the (R,G,B)-triplets (was counting some green for red)]
shiftLock happens

Philemon63
Posts: 1
Joined: Sun Feb 09, 2020 2:07 pm

Re: Fast method for counting RGB values of an image

Post by Philemon63 » Sun Feb 09, 2020 2:15 pm

Hello, I can't find the stack file "ImageStatistics_v165" here or anywhere else. Do you know where I can get it, please ? :idea:

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Fast method for counting RGB values of an image

Post by [-hh] » Sun Feb 09, 2020 7:15 pm

"Sample Stacks"/livecodeshare/revOnline doesn't work for me any more (impossible to upload/download large stacks) since several months. Thus I removed all my 64 stacks from there.
So: Sorry, but given time, in a few weeks, I'll make an own download page with some of these.
shiftLock happens

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Fast method for counting RGB values of an image

Post by FourthWorld » Sun Feb 09, 2020 7:51 pm

[-hh] wrote:
Sun Feb 09, 2020 7:15 pm
"Sample Stacks"/livecodeshare/revOnline doesn't work for me any more (impossible to upload/download large stacks) since several months. Thus I removed all my 64 stacks from there.
I would be happy to follow up with the team to see if we can resolve that. Is there a bug report on that? What was the size difference between the one that didn't work and the 64 that had been successfully uploaded?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Fast method for counting RGB values of an image

Post by [-hh] » Sun Feb 09, 2020 8:25 pm

The stacks were (nearly) all there, some since years. The problems started after the 'server change' last year.

The first limit was for up-/download stacks of size > 2-3 MByte. I reported to support, Robin removed that limit.
The limit changed again to (currently) stacks of size > 5-6 MByte. Reported again to support. Robin tried again but didn't succeed.
Several large stacks (around 6-13 MByte), especially of category imageTools, couldn't be updated or downloaded.
After several weeks I gave up.

But this is not worth to waste time of an elsewhere extremely busy team. I am currently looking into all these stacks and update some of them. And will publish these on an own download page.

[If you really want to test that then try to upload and download a stack of size (say) 10 MByte. Try also to delete that stack. Probably the server has a dataLimit (may occur if dataURLs are used)?]

@Philemon63 (link may become invalid after finishing my download page in a few weeks):
http://hyperhh.de/abcstacks/ImageStatis ... vecode.zip (5.1 MByte)
shiftLock happens

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Fast method for counting RGB values of an image

Post by FourthWorld » Sun Feb 09, 2020 8:37 pm

TorstenHolmer wrote:
Wed Jun 19, 2019 5:43 pm
my task is simple, I want to count the amount of RGB values of the pixels in an image: how often 201,10,10 occurs in the image etc.
How will this info be used?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Fast method for counting RGB values of an image

Post by FourthWorld » Sun Feb 09, 2020 9:39 pm

I just noticed the date in Bernd's code, 2013, possibly predating the deprecation of charToNum. With the introduction of Unicode the internal handling of a "character" is much more complex, and when working with bytes the new byte chunk type is recommended, along with byteToNum for conversions.

So if you take this line:

Code: Select all

put charToNum(char i+1  of tData) & "," & charToNum(char i+2 of tData) & "," & charToNum(char i+3 of tData) into tRGB
...and replace it with this:

Code: Select all

put byteToNum(byte i+1  of tData) & "," & byteToNum(byte i+2 of tData) & "," & byteToNum(byte i+3 of tData) into tRGB
...you may see a speed bump.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

[-hh]
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 2262
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

Re: Fast method for counting RGB values of an image

Post by [-hh] » Sun Feb 09, 2020 11:04 pm

LiveCode's byte-version is still 3-5 times slower than the (for that purpose non-optimized) JS version what is nevertheless a "bump" compared to the char-version.

Here is the script of a button (pure LCScript) you can use in my imageStatistics-stack for comparison (yields the same output using 256 bins for the frequencies of the rgb-triplets).

Code: Select all

-- computes the frequencies of used rgb-triplets of an image
-- [essentially a script by bn (Bernd Niggemann)]
on mouseUp
  set cursor to watch
  lock screen; lock messages
  put the millisecs into m1
  put the imageData of image the label of btn "images" into tData
  repeat with i = 1 to length(tData) - 4 step 4
    put byteToNum (byte i +1  of tData) & "," & byteToNum( byte i+2 of tData) & "," & byteToNum (byte i + 3 of tData) into tRGB
    add 1 to tArray[tRGB] -- make the RGB value the key of an array and add the frequency of that unique RGB value
  end repeat
  repeat for each key k in tArray
    put tArray[k],k & cr after s0
  end repeat
  sort s0 descending numeric by item 1 of each -- sort by frequency
  put "(+ " & the millisecs -m1 & " ms)" &cr& "Diff colors: " & the num of lines of s0 &cr& "Freq,R,G,B" & cr & \
        s0 into fld "distribution"
end mouseUp
  • For an image of size 1920x1080 I got (on a 2.5 GHz machine):
    2521 ms using the JS version,
    12710 ms using the LC byte version.
  • for an 640x480 image I got:
    373 ms using the JS version,
    1906 ms using the LC byte version.
shiftLock happens

Post Reply

Return to “Multimedia”