索贝尔过滤器使用

我无法实现Sobele滤波器的边缘检测。

首先,我使用SOBEL_VERTICAL和SOBEL_HORIZONTAL卷积,然后使用以下公式计算像素的颜色:G = sqrt(Gx * Gx + Gy * Gy)

码:

val log = KotlinLogging.logger { } val width = fastImage.width val height = fastImage.height override fun filter(): FastImage { val convolution = Convolution(fastImage) val obsSobelHorizontal = Observable.fromCallable { convolution.convolve(Convolution.SOBEL_HORIZONTAL) } val obsSobelVertical = Observable.fromCallable { convolution.convolve(Convolution.SOBEL_VERTICAL) } var fastImageSobel: FastImage? = null Observable.zip(obsSobelHorizontal, obsSobelVertical, { r1, r2 -> log.info { Thread.currentThread() } val fast = FastImage(width, height) for (x in 0..width - 1) { for (y in 0..height - 1) { val argb1: Int? = r1.getARGB(x, y) val argb2: Int? = r2.getARGB(x, y) if (argb1 != null && argb2 != null) { val G = sqrt(((argb1 * argb1) + (argb2 * argb2)).toDouble()).toInt().clamp() val color = Color(G,G,G) fast.setARGB(x, y, color.rgb) } } } return@zip fast }).subscribe({ fastImageSobel = it }, { log.error("Can`t do sobel!", it) }) return fastImageSobel!! } 

在这里输入图像描述 正确的形象是错误的

好吧,经过一番调查,我发现了什么是我的问题。 我的像素存储在RGB int数组中。 所以我必须为每个颜色通道手动计算G:

  val cx = Color(argb1) val cy = Color(argb2) val rx = cx.red val gx = cx.green val bx = cx.blue val ry = cy.red val gy = cy.green val by = cy.blue val R = Math.hypot(rx.toDouble(), ry.toDouble()).toInt().clamp() val G = Math.hypot(gx.toDouble(), gy.toDouble()).toInt().clamp() val B = Math.hypot(bx.toDouble(), by.toDouble()).toInt().clamp() val color = Color(R, G, B) fast.setARGB(x, y, color.rgb)