diff --git a/app/src/main/java/org/fairscan/app/PostProcessing.kt b/app/src/main/java/org/fairscan/app/PostProcessing.kt index e92cff3..a82ba26 100644 --- a/app/src/main/java/org/fairscan/app/PostProcessing.kt +++ b/app/src/main/java/org/fairscan/app/PostProcessing.kt @@ -40,21 +40,63 @@ fun enhanceCapturedImage(img: Mat): Mat { } } -fun isColoredDocument(img: Mat, threshold: Double = 4.0): Boolean { +fun isColoredDocument( + img: Mat, + chromaThreshold: Double = 20.0, + proportionThreshold: Double = 0.001 +): Boolean { val lab = Mat() Imgproc.cvtColor(img, lab, Imgproc.COLOR_BGR2Lab) + val channels = ArrayList() Core.split(lab, channels) + val a = channels[1] + val b = channels[2] - val aStd = MatOfDouble() - val bStd = MatOfDouble() - Core.meanStdDev(channels[1], MatOfDouble(), aStd) - Core.meanStdDev(channels[2], MatOfDouble(), bStd) + val aFloat = Mat() + val bFloat = Mat() + a.convertTo(aFloat, CvType.CV_32F) + b.convertTo(bFloat, CvType.CV_32F) - val result = (aStd.toArray()[0] + bStd.toArray()[0]) / 2.0 - return result > threshold + val aShifted = Mat() + val bShifted = Mat() + Core.subtract(aFloat, Scalar(128.0), aShifted) + Core.subtract(bFloat, Scalar(128.0), bShifted) + + val aSq = Mat() + val bSq = Mat() + Core.multiply(aShifted, aShifted, aSq) + Core.multiply(bShifted, bShifted, bSq) + + val sumSq = Mat() + Core.add(aSq, bSq, sumSq) + + val chroma = Mat() + Core.sqrt(sumSq, chroma) + + val mask = Mat() + Imgproc.threshold(chroma, mask, chromaThreshold, 1.0, Imgproc.THRESH_BINARY) + val coloredPixels = Core.countNonZero(mask) + + val totalPixels = chroma.rows() * chroma.cols() + val proportion = coloredPixels.toDouble() / totalPixels.toDouble() + + lab.release() + channels.forEach { it.release() } + aFloat.release() + bFloat.release() + aShifted.release() + bShifted.release() + aSq.release() + bSq.release() + sumSq.release() + chroma.release() + mask.release() + + return proportion > proportionThreshold } + private fun multiScaleRetinex(img: Mat, kernelSizes: List = listOf(30.0, 500.0)): Mat { // Convert to grayscale (1 channel) val gray = Mat()