Page 1 of 1
Image filter to cleanup scanned image
Posted: Fri Jul 11, 2025 4:22 pm
by acreis
A long time ago, someone published code that filtered an image—for example, a page from a book—removing the gray areas and leaving only the white paper and black letters. It seemed to be a filter algorithm. A convolution. Would anyone know the topic? I've already tried searching, even on Google."
Re: Image filter to cleanup scanned image
Posted: Fri Jul 11, 2025 5:44 pm
by mk-soft
I once wrote a gray filter.
I have customised this time also black and white filter.
Update
- Calculate black part
Code: Select all
;-TOP
; ***************************************************************************************
; Comment : 2D-ScaleGrayCallback
; Author : mk-soft
; File :
; Version : v1.02.1
; Date : 11.07.2025
; ***************************************************************************************
EnableExplicit
UseJPEGImageDecoder()
UsePNGImageDecoder()
; Fenster
Enumeration
#Main
EndEnumeration
; Gadgets
Enumeration
#ScrollArea
#Canvas
EndEnumeration
Global exit
Procedure ScaleGrayCallback(x, y, SourceColor.l, TargetColor.l)
Protected light
light = ((Red(TargetColor) * 30 + Green(TargetColor) * 59 + Blue(TargetColor) * 11) / 100)
ProcedureReturn RGBA(light, light, light, 255)
EndProcedure
; ----
; Filters to pure black and white image
Global lightMinCB
Global lightRangeCB
Procedure ScaleGrayFilterCallback(x, y, SourceColor.l, TargetColor.l)
Protected light
light = ((Red(TargetColor) * 30 + Green(TargetColor) * 59 + Blue(TargetColor) * 11) / 100)
If light > lightMinCB
; White
light = 255
Else
; Calulate Black
light = light * 255 / lightRangeCB
; Pure Black
;light = 0
EndIf
ProcedureReturn RGBA(light, light, light, 255)
EndProcedure
; ----
Procedure Draw(image)
Protected x, y, dx, dy, time, limit
dx = GadgetWidth(#Canvas)
dy = GadgetHeight(#Canvas)
time = ElapsedMilliseconds()
If StartDrawing(CanvasOutput(#Canvas))
DrawImage(ImageID(image), 0, 0, dx, dy)
DrawingMode(#PB_2DDrawing_CustomFilter)
;CustomFilterCallback(@ScaleGrayCallback())
; Set lightMax
limit = 35 ; Procent
lightMinCB = limit * 255 / 100 ; (0..255)
lightRangeCB = 255 - lightMinCB
CustomFilterCallback(@ScaleGrayFilterCallback())
Box(0, 0, dx, dy)
StopDrawing()
EndIf
time = ElapsedMilliseconds() - time
MessageRequester("Time", "" + time + "ms")
EndProcedure
Procedure Main()
Protected Event, file.s, image
If OpenWindow(#Main, #PB_Any, #PB_Any, 1024, 768, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
file = OpenFileRequester("Picture", "", "", 0)
If file
image = LoadImage(#PB_Any, file)
Else
End
EndIf
ScrollAreaGadget(#ScrollArea, 0, 0, WindowWidth(#Main), WindowHeight(#main), 3840, 2160)
CanvasGadget(#Canvas, 0, 0, 3840, 2160)
CloseGadgetList()
Draw(image)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
exit = #True
EndSelect
Until exit
EndIf
EndProcedure : Main()
Re: Image filter to cleanup scanned image
Posted: Fri Jul 11, 2025 9:33 pm
by acreis
Thanks mk-soft!
I understand your code, but the code I saw had a variable limit (in your code limit = 40), maybe somethig called adptative thresolding, I tested and the result were impressive. I saved the code but I dont remeber where.
See this image please:

Re: Image filter to cleanup scanned image
Posted: Sat Jul 12, 2025 12:17 am
by JHPJHP
Hi acreis,
This is something that can easily be done using
PB Interface to OpenCV.
Download included a couple examples and an image to test with.
•
cv_adaptive_threshold.pb: Right-mouse-click the window to open a context menu for additional options.
•
cv_adaptive_threshold_minimal.pb: Minimal example demonstrating how simple it is to use the interface.
Note: Only the parts of the interface required to run the examples were included in the download.
Re: Image filter to cleanup scanned image
Posted: Sun Jul 13, 2025 11:37 pm
by acreis
Really thanks JHPJHP, going to do some testing!
Re: Image filter to cleanup scanned image
Posted: Mon Jul 14, 2025 1:31 pm
by Olli
'2' digits are easy to place in this sudoku !