I’m working in a task for applying kmeans clustering algorithm from OpenCV with Kotlin inside of an android app.
I’m got a piece of code that works, and result is an a reduced colors of the original bitmap. But the original bitmap has a lot of transparent pixels but the result bitmap is returning black pixels in the place of the transparent pixels, but I need that the result keep untouched the transparent pixels.
My method is:
suspend fun calculateDominantQuantizationColors(inputBitmap: Bitmap): Bitmap? {
return withContext(Dispatchers.IO) {
try {
val imagen = Mat()
Utils.bitmapToMat(inputBitmap, imagen, true)
// Convertir el bitmap a una matriz de OpenCV (Mat)
val ny = Mat()
Utils.bitmapToMat(inputBitmap, ny, true)
// Convertir la imagen de RGB a BGR
val bgrImage = Mat()
Imgproc.cvtColor(ny, bgrImage, Imgproc.COLOR_RGB2BGR)
bgrImage.convertTo(bgrImage, CvType.CV_32F, 1.0 / 255.0)
// Convertir la imagen a escala de grises
val gres = Mat()
Imgproc.cvtColor(ny, gres, Imgproc.COLOR_BGR2GRAY)
// Calcular la intensidad mediana
val medianIntensity = Core.mean(gres).`val`[0]
// Calcular los umbrales inferior y superior iniciales
val lowerThreshold = 0.8 * medianIntensity
val upperThreshold = 1.6 * medianIntensity
// Aplicar detección de bordes Canny con los umbrales calculados
val edges = Mat()
Imgproc.Canny(gres, edges, lowerThreshold, upperThreshold)
// Encontrar contornos
val contours: MutableList<MatOfPoint> = ArrayList()
val hierarchy = Mat()
Imgproc.findContours(edges, contours, hierarchy, Imgproc.THRESH_BINARY, Imgproc.CHAIN_APPROX_SIMPLE)
// Reformar la imagen para el agrupamiento k-means
val reshapedImage = bgrImage.reshape(1, bgrImage.rows() * bgrImage.cols())
// Realizar agrupamiento k-means
val labels = Mat()
val K = 8
val centers = Mat(K, reshapedImage.cols(), reshapedImage.type())
val maxCount = 8
val criteria = TermCriteria(TermCriteria.EPS, maxCount, 2.0)
Core.kmeans(reshapedImage, K, labels, criteria, 1, Core.KMEANS_PP_CENTERS, centers)
// Reconstruir la imagen agrupada
var rec = Mat(bgrImage.rows() * bgrImage.cols(), 3, CvType.CV_32F)
for (i in 0 until reshapedImage.rows()) {
val j = labels.get(i, 0)[0].toInt()
centers.row(j).copyTo(rec.row(i))
}
// Reformar la imagen reconstruida al tamaño y tipo original
rec.convertTo(rec, CvType.CV_8U, 255.0)
rec = rec.reshape(3, bgrImage.rows())
Imgproc.cvtColor(rec, rec, Imgproc.COLOR_BGR2RGB)
// Aplicar un filtro bilateral
val biletra = Mat()
Imgproc.bilateralFilter(rec, biletra, 50, 50.0, 50.0, Core.BORDER_DEFAULT)
Imgproc.drawContours(biletra, contours, -1, Scalar(1.0, 1.0, 1.0), 1)
// Convertir la imagen procesada a Bitmap
val resultBitmap = Bitmap.createBitmap(biletra.cols(), biletra.rows(), Bitmap.Config.ARGB_8888)
Utils.matToBitmap(biletra, resultBitmap, true)
return@withContext resultBitmap
} catch (ex: Exception) {
ex.printStackTrace()
return@withContext null
}
}
}
I cannot upload images because my account is new. I’ve asked the same with images in the next stackoverflow post.
Any advice to achieve this will be appreciated.
Thank you