How can I perform a Otsu's method or another image thresholding process using Purebasic (source code wil be great).
Thx
Image thresholding process
Re: Image thresholding process
Hi ashz,
what do you have so far? we're happy to help out solving specific problems you encounter
what do you have so far? we're happy to help out solving specific problems you encounter
there is no sig, only zuul (and the following disclaimer)
WARNING: may be talking out of his hat
WARNING: may be talking out of his hat
Re: Image thresholding process
Normally you would provide what you have worked out so far and individuals will assist you if you get stuck. I was intrigued by your question though and created an example (not perfect) using Otsu's method which I translated from some java code found here.ashz wrote:How can I perform a Otsu's method or another image thresholding process using Purebasic (source code wil be great).
You load the picture and it will resize it to fit the square view windows, convert it to greyscale and then show the b/w image using Otsu's method for calculating the threshold. If you are curious you can move the trackbar and see if there are other threshold values that would have been better.
Code: Select all
UseJPEGImageDecoder()
UsePNGImageDecoder()
#True = 1
#False = 0
Procedure greyscale(img, Array srcData(1))
Protected width, height, x, y, gray, pixel
If Not IsImage(img) : ProcedureReturn #False : EndIf
StartDrawing(ImageOutput(img))
width = ImageWidth(img) - 1
height = ImageHeight(img) - 1
For y = 0 To height
For x = 0 To width
pixel = Point(x, y)
grey = Red(pixel) * 77 ; 0.2989 * 256 = 76.5184
grey + Green(pixel) * 150 ; 0.5870 * 256 = 150.2720
grey + Blue(pixel) * 29 ; 0.1140 * 256 = 29.1840
grey = grey >> 8 ; / 256
Plot(x, y, RGB(grey, grey, grey))
srcData(y * (width + 1) + x) = grey
Next
Next
StopDrawing()
ProcedureReturn #True
EndProcedure
Procedure createImageWithThreshold(img, Array srcData(1), threshold)
Protected width, height, x, y, gray, pixel
If Not IsImage(img) : ProcedureReturn #False : EndIf
StartDrawing(ImageOutput(img))
width = ImageWidth(img) - 1
height = ImageHeight(img) - 1
For y = 0 To height
For x = 0 To width
pixel = srcData(y * (width + 1) + x)
If pixel >= threshold
pixel = RGB(255, 255, 255)
Else
pixel = RGB(0, 0, 0)
EndIf
Plot(x, y, pixel)
Next
Next
StopDrawing()
ProcedureReturn #True
EndProcedure
Procedure otsu_threashold(Array srcData(1))
;The input is an array of bytes, srcData that stores the greyscale image
;Calculate histogram
Protected srcDataLength = ArraySize(srcData()), ptr, h
Protected Dim histData($FF)
While ptr < srcDataLength
h = $FF & srcData(ptr)
histData(h) + 1
ptr + 1
Wend
Protected.f sum, sumB, varMax, varBetween, mB, mF
Protected wB, wF, threshold
For t = 0 To $FF
sum + t * histData(t)
Next
For t = 0 To $FF
wB + histData(t) ;Weight Background
If wB = 0: Continue: EndIf
wF = srcDataLength - wB ;Weight Foreground
If wF = 0: Break: EndIf
sumB + t * histData(t)
mB = sumB / wB ;Mean Background
mF = (sum - sumB) / wF ;Mean Foreground
;Calculate Between Class Variance
varBetween = (mB - mF) * (mB - mF) * wB * wF
;Check If new maximum Found
If varBetween > varMax
varMax = varBetween
threshold = t
EndIf
Next
ProcedureReturn threshold
EndProcedure
Enumeration
;windows
#main_win = 0
;gadgets
#load_btn = 0
#sourceImage_img
#resultImage_img
#threshold_trk
#threshold_txt
;images
#originalImage = 0
#thresholdImage
EndEnumeration
#DisplayWidth = 250
#DisplayHeight = 250
OpenWindow(#main_win, 0, 0, 530, 350, "Otsu Threshold", #PB_Window_SystemMenu)
ButtonGadget(#load_btn, 0, 0, 100, 20, "Load Picture")
ImageGadget(#sourceImage_img, 10, 30, #DisplayWidth, #DisplayHeight, 0)
ImageGadget(#resultImage_img, 20 + #DisplayWidth, 30, #DisplayWidth, #DisplayHeight, 0)
TextGadget(#threshold_txt, 20 + #DisplayWidth - 55, 50 + #DisplayHeight, 55, 20, "Threshold:")
TrackBarGadget(#threshold_trk, 20 + #DisplayWidth, 50 + #DisplayHeight, 255, 20, 0, 255)
Define Event, EventGadget, FileName.s, threshold
Dim srcData(#DisplayWidth * #DisplayHeight - 1)
Repeat
Event = WaitWindowEvent(10)
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
Select EventGadget
Case #load_btn
;load picture
FileName = OpenFileRequester("Select source image:", "C:\*.*", "Image|*.png;*.jpg;*.bmp|All Files (*.*)|*.*", 0)
If FileName
If LoadImage(#originalImage, FileName)
If ImageWidth(#originalImage) <> #DisplayWidth Or ImageHeight(#originalImage) <> #DisplayHeight
ResizeImage(#originalImage, #DisplayWidth, #DisplayHeight)
EndIf
SetGadgetState(#sourceImage_img, ImageID(#originalImage))
;convert to greyscale
greyscale(#originalImage, srcData())
;get threshold
threshold = otsu_threashold(srcData())
CopyImage(#originalImage, #thresholdImage)
;create image based on threshold
createImageWithThreshold(#thresholdImage, srcData(), threshold)
SetGadgetState(#resultImage_img, ImageID(#thresholdImage))
SetGadgetState(#threshold_trk, threshold)
EndIf
EndIf
Case #threshold_trk
If GetGadgetState(#threshold_trk) <> threshold
threshold = GetGadgetState(#threshold_trk)
CopyImage(#originalImage, #thresholdImage)
;create image based on threshold
createImageWithThreshold(#thresholdImage, srcData(), threshold)
SetGadgetState(#resultImage_img, ImageID(#thresholdImage))
EndIf
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow

