Analyzing Data?

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: heatherlaine, Klaus, FourthWorld, robinmiller, kevinmiller

Post Reply
Violetskyart
Posts: 2
Joined: Mon Oct 10, 2016 11:31 pm

Analyzing Data?

Post by Violetskyart » Mon Nov 07, 2016 10:37 pm

The app I am working on is a drawing and music app. What I have so far is a drawing page.
My objective is to have the app analyze what color is used the most, and then have a song play based on that color.

I have the songs already picked out, and information about the mostly used colors.

If anyone knows how to "analyze" the most used color, please enlighten me.

If anyone has suggestions, feel free to let me know.

Here is the link:
https://www . dropbox . com/s/j3xw228ekckixdh/Lyrical%20Art . livecode?dl=0

atmosk
Posts: 28
Joined: Wed Feb 27, 2013 5:50 pm

Re: Analyzing Data?

Post by atmosk » Tue Nov 08, 2016 3:59 pm

I'm assuming your goal is to get more than just the 3 base colors so that means you'll have to get the hsv (hue, saturation and value) from it and then according to hue (probably enough unless you have like red, light red, dark red etc) match the color.

So first off, you'll need to get the rgb values (and I'm hoping you're using images, if not then I shall have made a fool out of myself :D) and that can be achieved with imagedata,

Code: Select all

on mouseUp
   put the imagedata of img "YOURIMAGE" into iData
   put the width of img "YOURIMAGE" into w
   put the height of img "YOURIMAGE" into h
   repeat with y = 0 to h
      repeat with x = 0 to w
         put charToNum(char (y  * w) + (x  * 4) + 2 of iData) into r
         put charToNum(char (y  * w) + (x  * 4) + 3 of iData) into g
         put charToNum(char (y  * w) + (x  * 4) + 4 of iData) into b
      end repeat
   end repeat
end mouseUp
With that you can go through every color.

Then we need to add the conversion to hsv,

Code: Select all

function RGBtoHSV r, g, b
   put 0 into h; put 0 into s; put 0 into v
   put min(r,g,b) into cmin
   put max(r,g,b) into cmax
   put cmax into v
   put cmax - cmin into d
   if (cmax > 0 AND cmax <> cmin) then put d / cmax into s
   else 
      put 0 into s
      put -1 into h
      return h,s,v
   end if
   if (r = cmax) then put (g-b) / d into h
   else if (g = cmax) then put 2+ (b-r) / d into h
   else put 4 + (r-g) / d into h
   put h * 60 into h
   if (h < 0) then add 360 to h
   return h,s,v
end RGBtoHSV
Used like so,

Code: Select all

put RGBtoHSV(r,g,b) into hsv;put item 1 of hsv into hue; put item 2 of hsv into sat; put item 3 of hsv into val;
Now, if you have preset colors like red, purple etc, then you can just set variables of that name to 0 at the start of your check and just add by 1 whenever you get the hue of red (iirc would in the range of 350-10) or purple.

Bit short on time, but I'll try to add/write a better explanation later :)
Last edited by atmosk on Wed Nov 09, 2016 2:44 am, edited 2 times in total.

Klaus
Posts: 10381
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Analyzing Data?

Post by Klaus » Tue Nov 08, 2016 5:02 pm

Hi Violetskyart,

1. welcome to the forum! :D

2. Since this is obviously NOT a special GAME question 8) ,
I will move this thread to the "Talking Livecode" forum.


Best

Klaus

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 5569
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Analyzing Data?

Post by dunbarx » Tue Nov 08, 2016 5:42 pm

Atmosk

Just tried your code. With an arbitrary image, I get a divide by 0 error at:

Code: Select all

if (r = cmax) then put (g-b) / d into h
"d" is zeroed out in the line

Code: Select all

 put cmax - cmin into d
But glancing at the code, it should do, exhaustively, just exactly what the OP wanted.

Craig

atmosk
Posts: 28
Joined: Wed Feb 27, 2013 5:50 pm

Re: Analyzing Data?

Post by atmosk » Wed Nov 09, 2016 2:40 am

Yup, goofed up the rgbtohsv a bit, but fixed it in the first post now so future visitors won't have to struggle with it.

Here's a complete solution though since I felt a bit bad for messing up :)

Code: Select all

on mouseUp
   answer Analyze("image")
end mouseUp

function Analyze targetImage
   //item 1 = the name, item 2 = min value from 0, item 3 = max value, item 4 = where we collect the matches
   put "red,0,12,0" into lookup
   put cr & "orange,13,41,0" after lookup
   put cr & "yellow,42,69,0" after lookup
   put cr & "green,70,166,0" after lookup
   put cr & "blue,167,251,0" after lookup
   put cr & "violet,252,305,0" after lookup
   put cr & "red,306,360,0" after lookup
   put the imagedata of img targetImage into iData
   put the width of img targetImage into w
   put the height of img targetImage into h
   repeat with y = 0 to h
      repeat with x = 0 to w
         put charToNum(char (y  * w) + (x  * 4) + 2 of iData) into r
         put charToNum(char (y  * w) + (x  * 4) + 3 of iData) into g
         put charToNum(char (y  * w) + (x  * 4) + 4 of iData) into b
         put RGBtoHSV(r,g,b) into hsv; put item 1 of hsv into hue; put item 2 of hsv into sat
         if (sat <> 0) then
            repeat with n = 1 to the num of lines in lookup
               if (hue >= item 2 of line n of lookup AND hue <= item 3 of line n of lookup) then 
                  add 1 to item 4 of line n of lookup
               end if
            end repeat
         end if
      end repeat
   end repeat
   put 0 into tmax
   repeat for each line l in lookup
      if (item 4 of l > tmax) then 
         put item 4 of l into tmax
         put l into cline
      end if
   end repeat
   return item 1 of cline
end Analyze

function RGBtoHSV r, g, b
   put 0 into h; put 0 into s; put 0 into v
   put min(r,g,b) into cmin
   put max(r,g,b) into cmax
   put cmax into v
   put cmax - cmin into d
   if (cmax > 0 AND cmax <> cmin) then put d / cmax into s
   else 
      put 0 into s
      put -1 into h
      return h,s,v
   end if
   if (r = cmax) then put (g-b) / d into h
   else if (g = cmax) then put 2+ (b-r) / d into h
   else put 4 + (r-g) / d into h
   put h * 60 into h
   if (h < 0) then add 360 to h
   return h,s,v
end RGBtoHSV
I reckon that color selection is a bit lacking so here's a site for getting a much wider selection of color names based on hue (sat and val as well if you're up for that monumental task), http://www.color-blindness.com/color-name-hue/

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

Re: Analyzing Data?

Post by [-hh] » Wed Nov 09, 2016 8:36 am

If you mean with "analyzing" to interpret the most frequent color, then this is rather a question of taste than question of programming...

If you mean statistical analyzing of the image data then you could use the full information of the color frequency distribution (contains all information of the color data). These are 3D values (R,G,B). From such a distribution you can derive statistical data (see Mathematical Statistics), you have for example for now the 'mode' of the frequency distribution. You could also build color-histograms (categorizing the data).

The following computes the frequency distribution of the RGB-colors of an image (not using the alphaByte A of ARGB, so we have 256*256*256=2^24=16777216 different colors available. Frequencies of zero (no occurence) are not listed.

Each line of the result has the form frequency,frequency%,R,G,B
and the lines are sorted top down by frequency.

Code: Select all

function frequencies iName -- iName = image name
  put the imageData of img iName into iData; put length(iData) div 4 into LL
  repeat with i=1 to LL
    add 1 to freq[byte 4*i-2 to 4*i of iData]
  end repeat
  repeat for each key k in freq
    put cr & freq[k] & "," & round(1000*freq[k]/LL)/10 & "%," & \
          byteToNum(byte 1 of k) &","& byteToNum(byte 2 of k) &","& \
          byteToNum(byte 3 of k) after rslt
  end repeat
  delete char 1 of rslt; sort rslt descending numeric by item 1 of each
  return rslt
end frequencies
Usage example.

Code: Select all

on mouseUp
  put the millisecs into m1
  lock screen; lock messages; set cursor to watch
  put frequencies ("img_1") into lst
  --# evaluating the top:
  --put item 3 to 5 of line 1 of lst into nb1
  --set backcolor of grc "nb1" to nb1
  --put hhClosestNamedColors(nb1) into fld "ClosestNamedColors"
  --put hhClosestSafeHexColors(nb1) into fld "ClosestSafeHexColors"
   put lst into fld "frequencies"
  unlock screen; unlock messages
  put the millisecs- m1 & " ms" into fld "timing"
end mouseUp
For evaluating/categorizing the mode (most frequent) colors or whatever you take from the ranking you could use the scripts of stack "colorHarmonies (= Raspi stack #41 , contains
hhClosestNamedColors(rgb) and hhClosestSafeHexColors(rgb)).

@atmosk.
I can't currently see any special advantage of using the hsv color model here. Do you have advantages in mind if one tries to categorize the used colors?
shiftLock happens

atmosk
Posts: 28
Joined: Wed Feb 27, 2013 5:50 pm

Re: Analyzing Data?

Post by atmosk » Wed Nov 09, 2016 10:59 am

[-hh] wrote:I can't currently see any special advantage of using the hsv color model here. Do you have advantages in mind if one tries to categorize the used colors?
The benefit was in the ease of use with dynamic colors, but your solution is way more efficient (like 1000 times faster?) than mine was so even if there was some benefits they equal to none just because of the gigantic performance difference.

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

Re: Analyzing Data?

Post by [-hh] » Wed Nov 09, 2016 4:54 pm

Hi atmosk.

The CPU time used doesn't matter this much if one applies techniques to a 'short' list like, say the USED COLORS (from the frequency ranking). So you are right, the OP could think about converting to other color models/displays (cmyk, dec, hex, hsl, hsv, ryb) for comparing/analyzing colors. Also, as you say, color blindness knowledge could be applied to the used colors. Also a simple concept of contrast of foreColor to backColor may come in (see stack #81 'ContrastRatio'.

For applying one-dimensional statistical formulas one could think about converting to decimal numbers, apply the formulas, and then convert the result (mean, median, standard deviation etc ...) back to rgb. Here are converter for that.

Code: Select all

-- example usage: put rgb2dec("100,200,50")
function rgb2dec rgb -- r=0-255, g=0-255, b=0-255
  -- put checkRGB into rgb
  return (item 1 of rgb)*2^16 + (item 2 of rgb)*2^8 + (item 3 of rgb)
end rgb2dec

Code: Select all

-- example usage: put dec2rgb("12345678") 
function dec2rgb d -- d = -- up to 8 digits in 0-16777215
  -- (16777215=2^24-1 because of 3 x 8 = 24 bit)
  -- minimal check for dec
  put value(d) into d; if d is not an integer then return "0,0,0"
  put max(0, min(16777215, d)) into d
  put d div 2^16 into r; put d mod 2^16 into d; put d div 2^8 into g
  return (r,g,d mod 2^8)
end dec2rgb
All converter (rgb to each of cmyk, dec, hex, hsl, hsv, ryb and these back to rgb) can be found in "colorHarmonies" cited above.
shiftLock happens

Violetskyart
Posts: 2
Joined: Mon Oct 10, 2016 11:31 pm

Re: Analyzing Data?

Post by Violetskyart » Mon Nov 14, 2016 10:54 pm

Thanks everyone for the suggestions. I am still having trouble getting this app to do what I want.
Attached is an example of the "Image" I am using. The code is a drawing app, using the pencil tool.
Each color then has its own card with information on it.
My goal is to have the most used color to go to its corresponding card. For example, if orange is the most used color in the image, it would go automatically to the orange card when the "Analyze" button is pressed.
Attachments
Screenshot 2016-11-14 16.25.01.png

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

Re: Analyzing Data?

Post by [-hh] » Mon Nov 14, 2016 11:23 pm

You have the methods for that available.

Simply use in your scripts RGB values instead of color names.
black = "0,0,0"
blue = "0,0,255"
green = "0,255,0"
grey = "128,128,128"
orange = "255,128,0"
purple = "128,0,128"
red = "255,0,0"
yellow = "255,255,0"

The most frequent color will mostly be white = "255,255,255", leave that out.
shiftLock happens

Post Reply

Return to “Talking LiveCode”