阅读 365

Android OpenCV(十二):极坐标变换

极坐标

极坐标系(polar coordinates)是指在平面内由极点、极轴和极径组成的坐标系。在平面上取定一点O,称为极点。从O出发引一条射线Ox,称为极轴。再取定一个单位长度,通常规定角度取逆时针方向为正。这样,平面上任一点P的位置就可以用线段OP的长度ρ以及从Ox到OP的角度θ来确定,有序数对(ρ,θ)就称为P点的极坐标,记为P(ρ,θ);ρ称为P点的极径,θ称为P点的极角。

极坐标和笛卡尔坐标的转换关系:

x = ρcosθ

y = ρsinθ

反过来也可以用过x, y 计算出ρ,θ的值

API

public static void warpPolar(Mat src, Mat dst, Size dsize, Point center, double maxRadius, int flags)
复制代码
  • 参数一:src,原图像,可以是灰度图像或者彩色图像。

  • 参数二:dst,极坐标变换后输出图像,与原图像具有相同的数据类型和通道数。

  • 参数三:dsize,目标图像大小。

  • 参数四:center,极坐标变换时极坐标的原点坐标。

  • 参数五:maxRadius,变换时边界圆的半径,它也决定了逆变换时的比例参数。

  • 参数六:flags, 插值方法与极坐标映射方法标志,插值方法和极坐标映射方法如下,两个方法之间通过“+”或者“|”号进行连接。

    // C++: enum InterpolationFlags
    public static final int
    INTER_NEAREST = 0,
    INTER_LINEAR = 1,
    INTER_CUBIC = 2,
    INTER_AREA = 3,
    INTER_LANCZOS4 = 4,
    INTER_LINEAR_EXACT = 5,
    INTER_MAX = 7,
    WARP_FILL_OUTLIERS = 8,
    WARP_INVERSE_MAP = 16;//逆变换
    复制代码
    // C++: enum WarpPolarMode
    public static final int
    WARP_POLAR_LINEAR = 0,//极坐标变换
    WARP_POLAR_LOG = 256;//半对数极坐标变换
    复制代码

操作

class PolarActivity : AppCompatActivity() {

private lateinit var mBinding: ActivityPolarBinding
private lateinit var mRgb: Mat
private lateinit var mPolar: Mat

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_polar)

val bgr = Utils.loadResource(this, R.drawable.circle)
mRgb = Mat()
Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)
showMat(mBinding.ivCircle, mRgb)
bgr.release()
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_polar, menu)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.polar -> {
polarTransform(mRgb)
}

R.id.reverse_polar -> {
if (!this::mPolar.isInitialized) {
Toast.makeText(this, "请先进行极坐标变换", Toast.LENGTH_SHORT).show()
} else {
reversePolarTransform(mPolar)
}
}
}
return true
}

private fun polarTransform(source: Mat) {
val center = Point(source.width() / 2.0, source.height() / 2.0)
mPolar = Mat()
val size = mRgb.size()
Imgproc.warpPolar(
source,
mPolar,
size,
center,
center.x,
Imgproc.INTER_LINEAR + Imgproc.WARP_POLAR_LINEAR
)
showMat(mBinding.ivResult, mPolar)
}

private fun reversePolarTransform(source: Mat) {
val center = Point(source.width() / 2.0, source.height() / 2.0)
val dst = Mat()
val size = mRgb.size()
Imgproc.warpPolar(
source,
dst,
size,
center,
center.x,
Imgproc.INTER_LINEAR + Imgproc.WARP_INVERSE_MAP
)
showMat(mBinding.ivResult, dst)
}


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

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

效果

极坐标变换
极坐标变换

源码

github.com/onlyloveyd/…

本文使用 mdnice 排版