How to detect Shadows with OpenCV on a face?

I am trying to detect shadows on an image with the help of many past topics but most of them either can not work too much heavy for a mobile CPU. This is the code that I built from a post which is going through each pixel and way too resource heavy.

I just want to draw contours on the image instead of removing the shadow.

The link to the post: how to detect and remove shadow of a object - OpenCV Q&A Forum

My Code:

    private fun getShadowContours(
        imgMat: Mat,
    ): Triple<List<MatOfPoint>, Mat, Mat> {
        val imageShadow = imgMat.clone()

        val dataRows = imageShadow.rows()
        val dataCols = imageShadow.cols()

        IntStream.range(5, dataRows - 5).parallel().forEach { i ->
            IntStream.range(5, dataCols - 5).parallel().forEach { j ->
                val pixelAddress = intArrayOf(i, j)
                val pixel = imageShadow.get(pixelAddress)
                val b: Int = pixel[0].toInt()
                val g: Int = pixel[1].toInt()
                val r: Int = pixel[2].toInt()

                val varR = (r / 255.0) //RGB from 0 to 255
                val varG = (g / 255.0)
                val varB = (b / 255.0)

                val varMin = min(min(varR, varG), varB) //Min. value of RGB

                val varMax = max(max(varR, varG), varB) //Max. value of RGB

                val deltaMax = varMax - varMin //Delta RGB value

                var h = 0.0
                var s = 0.0

                if (deltaMax != 0.0) {
                    s = deltaMax / varMax

                    val deltaR = ((varMax - varR) / 6 + deltaMax / 2) / deltaMax
                    val deltaG = ((varMax - varG) / 6 + deltaMax / 2) / deltaMax
                    val deltaB = ((varMax - varB) / 6 + deltaMax / 2) / deltaMax

                    if (varR == varMax) {
                        h = deltaB - deltaG
                    } else if (varG == varMax) {
                        h =
                            1 / 3 + deltaR - deltaB
                    } else if (varB == varMax) {
                        h = 2 / 3 + deltaG - deltaR
                    }

                    if (h < 0.0) h += 1
                    if (h > 1.0) h -= 1

                    //if(V>0.3 && V<0.85 && H<85 && S<0.15)
                    //if(V>0.5 && V<0.95 &&  S<0.2)
                    if (varMax > 0.3 && varMax < 0.95 && s < 0.2) {
                        imageShadow.put(pixelAddress, 0.0, 0.0, 0.0, 0.0)
                    } else {
                        imageShadow.put(pixelAddress, 255.0, 255.0, 255.0, 255.0)
                    }
                }
            }
        }

        val imageGray = Mat()
        Imgproc.cvtColor(imageShadow, imageGray, Imgproc.COLOR_RGB2GRAY)

        val dilationSize = 2.0
        val element = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE,
            Size((2 * dilationSize + 1), (2 * dilationSize + 1)),
            Point(dilationSize, dilationSize))

        Imgproc.dilate(imageGray, imageGray, element)

        val shadowHierarchy = Mat()
        var shadowContours: List<MatOfPoint> = ArrayList()
        Imgproc.findContours(imageGray,
            shadowContours,
            shadowHierarchy,
            Imgproc.RETR_TREE,
            Imgproc.CHAIN_APPROX_SIMPLE,
            Point(0.0, 0.0));

        val iW = imageShadow.width().toDouble()
        val iH = imageShadow.height().toDouble()

        shadowContours = shadowContours.parallelStream().filter {
            val area = Imgproc.contourArea(it)
            return@filter area > 400 && area < (iW * iH / 10.0)
        }.collect(Collectors.toList())

        return Triple(shadowContours, shadowHierarchy, imageShadow)
    }