Page 1 of 1

2D-Drawing Analysisfunctions

Posted: Sat Mar 14, 2015 2:50 pm
by mk-soft
Hi,

new analysis function for 2D-Drawing

Code: Select all

;-TOP

; ***************************************************************************************

; Comment   : Analysis Functions for 2D-Drawing
; Author    : mk-soft
; File      : 2D-Analysis.pbi
; Version   : v1.0
; Date      : 14.03.2015

; ***************************************************************************************

EnableExplicit

Structure udtAverageColors
  count.i
  red.i
  green.i
  blue.i
EndStructure

Define *AverageColors.udtAverageColors

Procedure AverageColorsCallback(x, y, SourceColor, TargetColor)
  
  Shared *AverageColors.udtAverageColors
  
  With *AverageColors
    \count + 1
    \red + Red(TargetColor)
    \green + Green(TargetColor)
    \blue + Blue(TargetColor)
  EndWith
  
  ProcedureReturn TargetColor
  
EndProcedure

; ---------------------------------------------------------------------------------------

Procedure AverageColorsBox(x, y, dx, dy)
  
  Shared *AverageColors.udtAverageColors
  
  Static buffer.udtAverageColors
  
  Protected r, g, b, result
  
  *AverageColors = @buffer
  
  With *AverageColors
    \count = 0
    \red = 0
    \green = 0
    \blue = 0
    
    DrawingMode(#PB_2DDrawing_CustomFilter)
  
    CustomFilterCallback(@AverageColorsCallback())
      
    Box(x, y, dx, dy, 0)
  
    DrawingMode(#PB_2DDrawing_Default)      
    
    r = \red / \count
    g = \green / \count
    b = \blue / \count
    result = RGB(r, g, b)
    
  EndWith
  
  ProcedureReturn result
    
EndProcedure

; ---------------------------------------------------------------------------------------

Procedure AverageColorsCircle(x, y, radius)
  
  Shared *AverageColors.udtAverageColors
  
  Static buffer.udtAverageColors
  
  Protected r, g, b, result
  
  *AverageColors = @buffer
  
  With *AverageColors
    \count = 0
    \red = 0
    \green = 0
    \blue = 0
    
    DrawingMode(#PB_2DDrawing_CustomFilter)
  
    CustomFilterCallback(@AverageColorsCallback())
      
    Circle(x, y, radius, 0)
  
    DrawingMode(#PB_2DDrawing_Default)      
    
    r = \red / \count
    g = \green / \count
    b = \blue / \count
    result = RGB(r, g, b)
    
  EndWith
  
  ProcedureReturn result
    
EndProcedure

; ---------------------------------------------------------------------------------------

Structure udtAverageLightness
  count.i
  light.i
EndStructure

Define *AverageLightness.udtAverageLightness

; l = r * 0.30 + g * 0.59 + b * 0.11

Procedure AverageLightnessCallback(x, y, SourceColor, TargetColor)
  
  Shared *AverageLightness.udtAverageLightness
  
  With *AverageLightness
    \count + 1
    \light + ((Red(TargetColor) * 30 + Green(TargetColor) * 59 + Blue(TargetColor) * 11) / 100)
  EndWith
  
  ProcedureReturn TargetColor
  
EndProcedure

; ---------------------------------------------------------------------------------------

Procedure.f AverageLightnessBox(x, y, dx, dy)
  
  Shared *AverageLightness.udtAverageLightness
  
  Static buffer.udtAverageLightness
  
  Protected r, g, b, result.f
  
  *AverageLightness = @buffer
  
  With *AverageLightness
    \count = 0
    \light = 0
    
    DrawingMode(#PB_2DDrawing_CustomFilter)
  
    CustomFilterCallback(@AverageLightnessCallback())
      
    Box(x, y, dx, dy, 0)
  
    DrawingMode(#PB_2DDrawing_Default)      
    
    result = \light / \count * 100 / 255
    
  EndWith
  
  ProcedureReturn result
    
EndProcedure

; ---------------------------------------------------------------------------------------

Procedure.f AverageLightnessCircle(x, y, radius)
  
  Shared *AverageLightness.udtAverageLightness
  
  Static buffer.udtAverageLightness
  
  Protected r, g, b, result.f
  
  *AverageLightness = @buffer
  
  With *AverageLightness
    \count = 0
    \light = 0
    
    DrawingMode(#PB_2DDrawing_CustomFilter)
  
    CustomFilterCallback(@AverageLightnessCallback())
      
    Circle(x, y, radius, 0)
  
    DrawingMode(#PB_2DDrawing_Default)      
    
    result = \light / \count * 100 / 255
    
  EndWith
  
  ProcedureReturn result
    
EndProcedure

; ---------------------------------------------------------------------------------------

Procedure CompareColors(color, comparecolor, tolerance)
  
  Protected r, g, b, cr, cg, cb, dr, dg, db, tol
  
  r = Red(color)
  g = Green(color)
  b = Blue(color)
  
  cr = Red(comparecolor)
  cg = Green(comparecolor)
  cb = Blue(comparecolor)
  
  dr = r - cr
  dg = g - cg
  db = b - cb
  
  If dr < 0 : dr * -1 : EndIf
  If dg < 0 : dg * -1 : EndIf
  If db < 0 : db * -1 : EndIf
  
  tol = tolerance / 2
  
  If dr < tol And dg < tol And db < tol
    ProcedureReturn #True
  EndIf
  
  ProcedureReturn #False
  
EndProcedure

; ***************************************************************************************

Example 1: find color

Code: Select all

;-TOP

; ***************************************************************************************

; Comment   : Analysis Functions for 2D-Drawing Exsample 1
; Author    : mk-soft
; File      : 
; Version   : v1.0
; Date      : 14.03.2015

; ***************************************************************************************


EnableExplicit

UseJPEGImageDecoder()

IncludeFile "2D-Analysis.pbi"

; Fenster
Enumeration
  #Main
EndEnumeration

; Gadgets
Enumeration
  #Canvas
EndEnumeration

Global exit

Procedure CreatePicture(dx,dy)
  
  Protected result, x, y, r, color, c
  
  result = CreateImage(#PB_Any, 800, 600, 32, $C0C0C0)
  If result
    If StartDrawing(ImageOutput(result))
      Repeat
        x = Random(dx-1)
        y = Random(dy-1)
        r = Random(40, 10)
        color = RGB(Random(255), Random(255), Random(255))    
        Circle(x, y, r, color)
        c + 1
      Until c > 2000
      StopDrawing()
    Else
      Debug "Error create image"
      End
    EndIf
  EndIf
  
  ProcedureReturn result
  
EndProcedure

Procedure Draw(image)
  
  Protected x, y, dx, dy, r, c, c2, size
  Protected backcolor, color , compare, lightness
  
  backcolor = RGB(192,192,192)
  
  dx = GadgetWidth(#Canvas)
  dy = GadgetHeight(#Canvas)
  
  If StartDrawing(CanvasOutput(#Canvas))
    
    DrawImage(ImageID(image), 0, 0, dx, dy)
    
    Debug AverageLightnessBox(0, 0, dx, dy)
    
    ; Check
    compare = $808080
    #size = 15
    
    Debug "Search color $" + Hex(compare) 
    
    For y = 0 To dy - 1 Step #size
      For x = 0 To dx - 1 Step #size
        color = AverageColorsBox(x, y, #size, #size)
        ;Box(x, y, #size, #size, color)
        
        If CompareColors(color, compare, 40)
          Debug "Found on " + Str(x) + ", " + Str(y)
          Debug "Lightness " + StrF(AverageLightnessBox(x,y, #size, #size), 1) + "%"
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(x, y, #size, #size, $000000FF)
        EndIf
      Next
      
    Next
    
    StopDrawing()
    
  EndIf
  
EndProcedure

Procedure Main()
  
  Protected Event, file.s, image
  
  If OpenWindow(#Main, #PB_Any, #PB_Any, 800, 600, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    file = OpenFileRequester("Picture", "", "", 0)
    If file
      image = LoadImage(#PB_Any, file)
    Else
      image = CreatePicture(800,600)
    EndIf
    
    CanvasGadget(#Canvas, 5, 5, WindowWidth(#Main) - 10, WindowHeight(#Main) - 10)
    
    Draw(image)
    
    Repeat
      Event = WaitWindowEvent()
      
      Select Event
          
        Case #PB_Event_CloseWindow
          exit = #True
          
      EndSelect
      
    Until exit
    
  EndIf
    
EndProcedure : Main()
:wink:

Re: 2D-Drawing Analysisfunctions

Posted: Sat Mar 14, 2015 10:28 pm
by mk-soft
Added new example :wink:

Example 2: lightness

Code: Select all

;-TOP

; ***************************************************************************************

; Comment   : Analysis Functions for 2D-Drawing Exsample 1
; Author    : mk-soft
; File      : 
; Version   : v1.0
; Date      : 14.03.2015

; ***************************************************************************************


EnableExplicit

UseJPEGImageDecoder()

IncludeFile "2D-Analysis.pbi"

; Fenster
Enumeration
  #Main
EndEnumeration

; Gadgets
Enumeration
  #Canvas
EndEnumeration

Global exit

Procedure CreatePicture(dx,dy)
  
  Protected result, x, y, r, color, c
  
  result = CreateImage(#PB_Any, 800, 600, 32, $C0C0C0)
  If result
    If StartDrawing(ImageOutput(result))
      Repeat
        x = Random(dx-1)
        y = Random(dy-1)
        r = Random(40, 10)
        color = RGB(Random(255), Random(255), Random(255))    
        Circle(x, y, r, color)
        c + 1
      Until c > 2000
      StopDrawing()
    Else
      Debug "Error create image"
      End
    EndIf
  EndIf
  
  ProcedureReturn result
  
EndProcedure

Procedure Draw(image)
  
  Protected x, y, dx, dy, r, c, c2, size
  Protected backcolor, color , compare, lightness.f
  
  backcolor = RGB(192,192,192)
  
  dx = GadgetWidth(#Canvas)
  dy = GadgetHeight(#Canvas)
  
  If StartDrawing(CanvasOutput(#Canvas))
    
    DrawImage(ImageID(image), 0, 0, dx, dy)
    
    #size = 10
    
    For y = 0 To dy - 1 Step #size
      For x = 0 To dx - 1 Step #size
        lightness = AverageLightnessBox(x, y, #size, #size)
        
        If lightness > 70.0
          Debug "Found on " + Str(x) + ", " + Str(y)
          Debug "Lightness " + lightness + "%"
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(x, y, #size, #size, $000000FF)
        EndIf
      Next
      
    Next
    
    StopDrawing()
    
  EndIf
  
EndProcedure

Procedure Main()
  
  Protected Event, file.s, image
  
  If OpenWindow(#Main, #PB_Any, #PB_Any, 800, 600, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    file = OpenFileRequester("Picture", "", "", 0)
    If file
      image = LoadImage(#PB_Any, file)
    Else
      image = CreatePicture(800,600)
    EndIf
    
    CanvasGadget(#Canvas, 5, 5, WindowWidth(#Main) - 10, WindowHeight(#Main) - 10)
    
    Draw(image)
    
    Repeat
      Event = WaitWindowEvent()
      
      Select Event
          
        Case #PB_Event_CloseWindow
          exit = #True
          
      EndSelect
      
    Until exit
    
  EndIf
    
EndProcedure : Main()