Code: Select all
EnableExplicit
; (c) Lunasole, 2016/03/10
Procedure RGBtoGray (RGB)
ProcedureReturn (Red(RGB) * 0.3 + Green(RGB) * 0.59 + Blue(RGB) * 0.11) ; photoshop, GIMP?
;; here comes more ^^
; Gray = (Red + Green + Blue) / 3 ; averaging
; Gray = (Red * 0.2126 + Green * 0.7152 + Blue * 0.0722)
; Gray = (Red * 0.299 + Green * 0.587 + Blue * 0.114)
; ; Max() returns max of 3 arguments, Min() does the same but minimal value returned
; Gray = ( Max(Red, Green, Blue) + Min(Red, Green, Blue) ) / 2 ; desaturation
; Gray = Max(Red, Green, Blue) ; maximum decomposition
; Gray = Min(Red, Green, Blue) ; minumum decomposition
; Gray = Red ; Green/Blue ; single color channel
EndProcedure
;; Bradley local image thresholding
; hDC: valid output handle (ImageID(), CanvasID() and so on)
; WhiteBound: 0.0 to 1.0
; Details: 0.0 to 1.0, the higher it is, the lesser is area size and more areas used
; RETURN: none, original image modified
Procedure imageToWB(hDC, WhiteBound.f = 0.15, Details.f = 0.32)
If Not StartDrawing(hDC)
ProcedureReturn
EndIf
Protected src_width = OutputWidth(), src_height = OutputHeight()
Protected X, Y, X1, Y1, X2, Y2
Protected Summ, AreaDim, AreaSize = ((src_width + src_height) / 2) * (1.0 - Details)
Protected.L Dim IntegralImage (src_width - 1, src_height - 1)
Protected.A Dim GrayImage (src_width - 1, src_height - 1)
; building grayscale and integral images
For X = 0 To src_width - 1
Summ = 0
For Y = 0 To src_height - 1
GrayImage(X, Y) = RGBtoGray(Point(X, Y))
Summ + GrayImage(X, Y)
If X = 0
IntegralImage(X, Y) = Summ
Else
IntegralImage(X, Y) = IntegralImage(X - 1, Y) + Summ
EndIf
Next Y
Next X
; walk to local areas
For X = 0 To src_width - 1
For Y = 0 To src_height - 1
X1 = X - AreaSize
X2 = X + AreaSize
Y1 = Y - AreaSize
Y2 = Y + AreaSize
If x1 < 0 : x1 = 0 : EndIf
If x2 >= src_width : x2 = src_width - 1 : EndIf
If y1 < 0 : y1 = 0 : EndIf
If y2 >= src_height : y2 = src_height - 1: EndIf
AreaDim = (X2 - X1) * (Y2 - Y1)
Summ = IntegralImage(X2, Y2) - IntegralImage(X2, Y1) - IntegralImage(X1, Y2) + IntegralImage(X1, Y1) ; quickly get whole area brightness by calculating brightness values at area corners
If (GrayImage(X, Y) * AreaDim) >= (Summ * (1.0 - WhiteBound))
Plot(X, Y, #White)
Else
Plot(X, Y, #Black)
EndIf
Next Y
Next X
; cls
StopDrawing()
FreeArray(IntegralImage())
FreeArray(GrayImage())
EndProcedure
;;;;;;;;;
UsePNGImageDecoder()
UseJPEGImageDecoder()
Define A = LoadImage(#PB_Any, #PB_Compiler_Home+"/Examples/Sources/data/purebasic.bmp")
OpenWindow(0, 0, 0, ImageWidth(A), ImageHeight(A) * 2, "Img", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, ImageWidth(A), ImageHeight(A)) ; original image
CanvasGadget(1, 0, ImageHeight(A), ImageWidth(A), ImageHeight(A)) ; modified one
SetGadgetAttribute(0, #PB_Canvas_Image, ImageID(A))
SetGadgetAttribute(1, #PB_Canvas_Image, ImageID(A))
; the function params need to be tweaked depend of what you need
imageToWB (CanvasOutput(1), 0.27)
Repeat
If WaitWindowEvent(256) = #PB_Event_CloseWindow
End
EndIf
ForEver