Liberty BASIC Community Forum
Liberty BASIC Programming Discussions >> Liberty BASIC Code >> Tree ring counter-ager
http://libertybasic.conforums.com/index.cgi?board=LB3&action=display&num=1465769697

Tree ring counter-ager
Post by tenochtitlanuk on Jun 12th, 2016, 5:14pm

What i love about LB is being able so quickly to trial /improve an idea.

I took some photos today in the Scottish forests- beautiful at this time of year- and idly wondered if I could make a tree ring counter. Half an hour later I'm getting graphics like that below. Presently doing a 4-pixel running average along a single cross section, but it looks like I'll need to average above & below the line too.
(the yellow lines are presently added by hand) There's potential too to associate ring-spacing with growing conditions in each year.

Fun! Especially as the tree I'm using is ( was) half my age...

User Image

Code:
    WindowWidth  =1008
    WindowHeight = 750

    nomainwin

    dim pixels( 1000)

    graphicbox  #w.gb,  1, 1, 1000, 702


    open "Tree Ring counter" for window as #w

        #w  "trapclose [quit]"

        handleg  =hwnd( #w.gb)
        calldll  #user32, "GetDC", handleg as ulong, hDC as ulong

        loadbmp "scr", "treerings.bmp"
        #w.gb "down ; drawbmp scr 1 1"

        for x =0 to 1000
            yy =402
            calldll #gdi32, "GetPixel", hDC as ulong, x as long, yy as long, pixcol as ulong
            bl = int(  pixcol /( 256*256)): gr = int( (pixcol -bl *256*256) / 256): re = int(  pixcol -bl *256*256 -gr *256)
            pixels( x) =re
            '#w.gb "line "; x; " 430 "; x; " "; 430 -re
        next x

        #w.gb "color cyan"
        runningAve4 =( pixels( 0) +pixels( 1) +pixels( 2) +pixels( 3)) /3
        for x =3 to 1000
            runningAve4 =runningAve4 *0.75 +pixels( x) *0.25
            if x mod 2 then #w.gb "color black" else #w.gb "color cyan"
            #w.gb "line "; x; " 430 "; x; " "; 430 -runningAve4
        next x

        #w.gb "getbmp scr 1 1 1000 702"
        bmpsave "scr", "ringStats.bmp"

        wait


  [quit]
    close #w
    callDll #user32, "ReleaseDC", handleg as ulong, hDC as ulong, result as ushort
    end
 

Re: Tree ring counter-ager
Post by tenochtitlanuk on Jun 13th, 2016, 2:42pm

It actually proved quite tricky to allow for the basically noisy image. I got there, near enough, by blurring the image and sampling above and below the transect, and by doing a running average. Then look to see if brightness is rising or falling... and even then I had to mask the background manually!

It agrees quite well with what humans see- & shows just how good our visual processing is compared with a computer!

User Image

Code:
    WindowWidth  =1008
    WindowHeight = 750

    nomainwin

    dim pixels( 1000)

    graphicbox  #w.gb,  1, 1, 1001, 702


    open "Tree Ring counter" for window as #w

        #w  "trapclose [quit]"

        handleg  =hwnd( #w.gb)
        calldll  #user32, "GetDC", handleg as ulong, hDC as ulong

        loadbmp "scr", "treeringsBlurred5.bmp"
        #w.gb "down ; drawbmp scr 1 1 ; flush"

        for x =0 to 1000
            for y =-3 to 3
                yy          =430 +y
                calldll #gdi32, "GetPixel", hDC as ulong, x as long, yy as long, pixcol as ulong
                bl          =int(  pixcol /( 256*256)): gr = int( (pixcol -bl *256*256) / 256): re = int(  pixcol -bl *256*256 -gr *256)
                pixels( x)  =re +bl
                if gr <30 then pixels( x) =pixels( x) +gr
            next y
        next x

        #w.gb "color cyan"
        runningAve6 =( pixels( 0) +pixels( 1) +pixels( 2) +pixels( 3) +pixels( 4) +pixels( 5)) /6
        deltaX      =0

        for x =3 to 1000
            oldRunningAve6  =runningAve6
            runningAve6     =runningAve6 +pixels( x) *0.25 -pixels( x -3) *0.25
            deltaX          =runningAve6 -oldRunningAve6
            '#w.gb "color white"
            if deltaX > 1       then #w.gb "color red":         now$ ="red"
            if deltaX <-1       then #w.gb "color darkblue":    now$ ="darkblue"
            if abs( deltaX) <1  then #w.gb "color 60 60 60"
            #w.gb "line "; x -2; " "; 426 -runningAve6 /10; " "; x -2; " "; 426
            if was$ <>now$ then age2 =age2 +1
            was$ =now$
        next x

        #w.gb "font arial 24"
        #w.gb "up ; goto 40 412 ; down"
        #w.gb "\"; str$( int( age2 /4))

        #w.gb "getbmp scr 1 1 1000 702"
        bmpsave "scr", "ringStats5.bmp"

        wait

  [quit]
    close #w
    callDll #user32, "ReleaseDC", handleg as ulong, hDC as ulong, result as ushort
    end
 

Re: Tree ring counter-ager
Post by robmcal on Jun 13th, 2016, 11:16pm

Neat program!
Re: Tree ring counter-ager
Post by tsh73 on Jun 14th, 2016, 1:44pm

Cool idea, John.
Re: Tree ring counter-ager
Post by tenochtitlanuk on Jun 17th, 2016, 5:38pm

I wrote the program in spare time on a family holiday. In a beautiful example of serendipity, I was in the Scottish Borders town of Peebles, well known as home of author John Buchan, whose 'The Thirty Nine Steps' is famous as a novel and film. And see how many growth rings my software counted!