索贝尔滤波器实现
Sobel filter imlementation
我在实施用于边缘检测的 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)
我在实施用于边缘检测的 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)