阅读 325

Android OpenCV(九):LUT查找表

LUT查找表

LUT查找表,即像素灰度值的映射表,它以像素灰度值作为索引,以灰度值映射后的数值作为表中的内容。可以类比为我们编程过程中使用的Map,Key为像素灰度值,Value为灰度值映射后的数值。

API

public static void LUT(Mat src, Mat lut, Mat dst)
复制代码
  • 参数一:src,输入图像矩阵,其数据类型只能是CV_8U
  • 参数二:lut,256个像素灰度值的查找表,单通道或者与src通道数相同
  • 参数三:dst,输出图像矩阵,其尺寸与src相同,数据类型与lut相同

若第二个参数为单通道,则输入变量中的每个通道都按照一个LUT查找表进行映射。如果第二个参数是多通道,则输入变量中的第i个通道按照第二个参数的第i个通道LUT查找表进行映射。函数输出图像的数据类型不与原图像的数据类型保持一致,而是和LUT查找表的数据类型保持一致,这是因为将原灰度值映射到新的空间中,因此需要与新空间中的数据类型保持一致。

操作

class LutActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityLutBinding
private lateinit var mRgb: Mat
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_lut)

mRgb = Mat()
val bgr = Utils.loadResource(this, R.drawable.lena)
Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)
showMat(mRgb)
bgr.release()

mBinding.btLutMulti.setOnClickListener {
doLutMulti()
}

mBinding.btLutSingle.setOnClickListener {
doLutSingle()
}
}

private fun doLutSingle() {
val lutOneByteArray = ByteArray(256)
for (i in 0..255) {
if (i in 0..100) lutOneByteArray[i] = 0
if (i in 101..200) lutOneByteArray[i] = 100
if (i > 200) lutOneByteArray[i] = 255.toByte()
}
val lutTable = Converters.vector_uchar_to_Mat(lutOneByteArray.toList())
val result = Mat()
Core.LUT(mRgb, lutTable, result)
showMat(result)
}

private fun doLutMulti() {
val lutOneByteArray = ByteArray(256)
for (i in 0..255) {
if (i in 0..100) lutOneByteArray[i] = 0
if (i in 101..200) lutOneByteArray[i] = 100
if (i > 200) lutOneByteArray[i] = 255.toByte()
}
val lutOne = Converters.vector_uchar_to_Mat(lutOneByteArray.toList())

val lutTwoByteArray = ByteArray(256)
for (i in 0..255) {
if (i in 0..100) lutOneByteArray[i] = 0
if (i in 101..150) lutOneByteArray[i] = 100
if (i in 151..200) lutOneByteArray[i] = 150.toByte()
if (i > 200) lutOneByteArray[i] = 255.toByte()
}

val lutTwo = Converters.vector_uchar_to_Mat(lutTwoByteArray.toList())

val lutThreeByteArray = ByteArray(256)
for (i in 0..255) {
if (i in 0..100) lutOneByteArray[i] = 100
if (i in 101..200) lutOneByteArray[i] = 200.toByte()
if (i > 200) lutOneByteArray[i] = 255.toByte()
}
val lutThree = Converters.vector_uchar_to_Mat(lutThreeByteArray.toList())

val lutTable = Mat()
Core.merge(listOf(lutOne, lutTwo, lutThree), lutTable)
lutOne.release()
lutTwo.release()
lutThree.release()

val result = Mat()
Core.LUT(mRgb, lutTable, result)
showMat(result)

lutTable.release()
result.release()
}


private fun showMat(source: Mat) {
val bitmap = Bitmap.createBitmap(source.width(), source.height(), Bitmap.Config.ARGB_8888)
Utils.matToBitmap(source, bitmap)
mBinding.ivLena.setImageBitmap(bitmap)
}

override fun onDestroy() {
mRgb.release()
super.onDestroy()
}
}
复制代码

结果

源码

github.com/onlyloveyd/…

本文使用 mdnice 排版