2D: Rate image sharpness
Posted: Mon Jul 29, 2024 10:02 am
Hi folks, while sorting and deleting holiday photos, I had the idea that it would be very helpful to have a sharpness rating for each picture. Especially if a series was taken and only the best (sharpest?) image should be kept.
So far I have used the image size for this, because the JPG encoder can compress blurred images better and in this case the image with the largest file size is the sharpest.
Has anyone ever made such considerations or had experience with them that could be shared here?
The AI claims there are the following 3 methods:
- Laplacian variance method
- Tenengrad method
- Brenner gradient method
The functions spit out completely different values, which would still have to be transformed to a scale.
What do you think, does that make sense?
So far I have used the image size for this, because the JPG encoder can compress blurred images better and in this case the image with the largest file size is the sharpest.
Has anyone ever made such considerations or had experience with them that could be shared here?
The AI claims there are the following 3 methods:
- Laplacian variance method
- Tenengrad method
- Brenner gradient method
The functions spit out completely different values, which would still have to be transformed to a scale.
What do you think, does that make sense?
Code: Select all
UseJPEGImageDecoder()
; Diese Methode berechnet die Summe der quadratischen Differenzen zwischen benachbarten Pixeln.
Procedure.d CalculateBrennerGradient(ImageID)
Protected x, y, brenner, gradient
Protected sum.d, count.d
If StartDrawing(ImageOutput(ImageID))
For y = 0 To ImageHeight(ImageID) - 1
For x = 0 To ImageWidth(ImageID) - 3
gradient = Red(Point(x + 2, y)) - Red(Point(x, y))
brenner + gradient * gradient
count + 1
Next
Next
StopDrawing()
EndIf
ProcedureReturn brenner
EndProcedure
; Berechnet die Laplacian-Varianz des Bildes.
Procedure.d CalculateLaplacianVariance(ImageID)
Protected x, y, pixel, laplacian, variance, mean
Protected Dim laplaceArray.d(1023, 1023)
Protected sum.d, sumSq.d, count.d
If StartDrawing(ImageOutput(ImageID))
For y = 1 To ImageHeight(ImageID) - 2
For x = 1 To ImageWidth(ImageID) - 2
; Laplacian kernel: [[0, 1, 0], [1, -4, 1], [0, 1, 0]]
laplacian = Red(Point(x, y + 1)) + Red(Point(x, y - 1)) + Red(Point(x + 1, y)) + Red(Point(x - 1, y)) - 4 * Red(Point(x, y))
laplaceArray(x, y) = laplacian
sum + laplacian
sumSq + laplacian * laplacian
count + 1
Next
Next
StopDrawing()
EndIf
mean = sum / count
variance = (sumSq / count) - (mean * mean)
ProcedureReturn variance
EndProcedure
; Tenengrad Methode:
; Diese Methode verwendet den Sobel-Operator, um die Kanten im Bild zu erkennen und die Schärfe zu bewerten.
Procedure.d CalculateTenengrad(ImageID)
Protected x, y, gx, gy, gradient, meanGradient
Protected sum.d, count.d
If StartDrawing(ImageOutput(ImageID))
For y = 1 To ImageHeight(ImageID) - 2
For x = 1 To ImageWidth(ImageID) - 2
; Sobel kernels
gx = -Red(Point(x - 1, y - 1)) - 2 * Red(Point(x - 1, y)) - Red(Point(x - 1, y + 1)) + Red(Point(x + 1, y - 1)) + 2 * Red(Point(x + 1, y)) + Red(Point(x + 1, y + 1))
gy = -Red(Point(x - 1, y - 1)) - 2 * Red(Point(x, y - 1)) - Red(Point(x + 1, y - 1)) + Red(Point(x - 1, y + 1)) + 2 * Red(Point(x, y + 1)) + Red(Point(x + 1, y + 1))
gradient = Sqr(gx * gx + gy * gy)
sum + gradient
count + 1
Next
Next
StopDrawing()
EndIf
meanGradient = sum / count
ProcedureReturn meanGradient
EndProcedure
Procedure.d NormalizeValue(value.d, min.d, max.d, newMin.d, newMax.d)
ProcedureReturn (value - min) / (max - min) * (newMax - newMin) + newMin
EndProcedure
OpenWindow(0, 0, 0, 900, 800, "")
; Load and convert image to grayscale
LoadImage(0, "C:\Temp\test_blur.jpg")
ImageGadget(0, 10, 10, ImageWidth(0), ImageHeight(0), ImageID(0))
;ConvertImage(0, #PB_Image_Grayscale)
meanGradient = CalculateTenengrad(0)
Debug "Tenengrad: " + StrD(meanGradient)
variance = CalculateLaplacianVariance(0)
Debug "Laplacian Varianz: " + StrD(variance)
brenner = CalculateBrennerGradient(0)
Debug "Brenner Gradient: " + StrD(brenner)
LoadImage(0, "C:\Temp\test_sharp.jpg")
ImageGadget(0, 10, 10, ImageWidth(0), ImageHeight(0), ImageID(0))
meanGradient = CalculateTenengrad(0)
Debug "Tenengrad: " + StrD(meanGradient)
variance = CalculateLaplacianVariance(0)
Debug "Laplacian Varianz: " + StrD(variance)
brenner = CalculateBrennerGradient(0)
Debug "Brenner Gradient: " + StrD(brenner)