Android 版本 OpenCV 计算图像的矩(Moments)
在 Android OpenCV 中,可以使用 Imgproc.moments() 方法计算图像的几何矩、中心矩和 Hu 不变矩(Hu Moments) 。这些矩可用于 计算质心(Centroid) 、图像形状分析、目标检测 以及 模式识别。
1. OpenCV 矩(Moments)的作用
• 几何矩(Geometric Moments) :计算图像的基本属性,如面积、质心、方向等。
• 中心矩(Central Moments) :消除图像的平移影响,使得计算结果不依赖于目标在图像中的位置。
• 归一化矩(Normalized Moments) :进一步消除尺度影响,使得矩与目标大小无关。
• Hu 不变矩(Hu Moments) :在旋转、缩放和平移变换下保持不变,用于形状匹配和目标识别。
2. 在 OpenCV Android 中计算图像的矩
(1) 依赖配置
在 build.gradle 中添加 OpenCV 依赖:
implementation 'org.opencv:opencv-android:4.5.1'
(2) 计算几何矩、中心矩和 Hu 不变矩
下面的代码示例展示了如何在 Android OpenCV 中计算图像的矩,并提取 质心、面积、方向和 Hu 矩。
完整代码
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Moments;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
public class MomentsActivity extends AppCompatActivity {
static {
OpenCVLoader.initDebug(); // 初始化 OpenCV
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 加载图像
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_image);
Mat imgMat = new Mat();
Utils.bitmapToMat(bitmap, imgMat);
// 转换为灰度图
Mat grayMat = new Mat();
Imgproc.cvtColor(imgMat, grayMat, Imgproc.COLOR_BGR2GRAY);
// 进行二值化处理
Mat binaryMat = new Mat();
Imgproc.threshold(grayMat, binaryMat, 128, 255, Imgproc.THRESH_BINARY);
// 计算图像的矩
Moments moments = Imgproc.moments(binaryMat, true);
// 计算质心
double cx = moments.get_m10() / moments.get_m00();
double cy = moments.get_m01() / moments.get_m00();
System.out.println("质心坐标: (" + cx + ", " + cy + ")");
// 在图像上绘制质心
Imgproc.circle(imgMat, new Point(cx, cy), 5, new Scalar(0, 0, 255), -1);
// 计算 Hu 不变矩
double[] huMoments = new double[7];
Imgproc.HuMoments(moments, huMoments);
// 打印 Hu 矩
System.out.println("Hu 不变矩:");
for (int i = 0; i < huMoments.length; i++) {
System.out.println("I" + (i + 1) + ": " + huMoments[i]);
}
// 将结果转换回 Bitmap 并显示
Bitmap resultBitmap = Bitmap.createBitmap(imgMat.cols(), imgMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(imgMat, resultBitmap);
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageBitmap(resultBitmap);
}
}
3. 代码解析
(1) 图像预处理
• 转换为灰度图:
Imgproc.cvtColor(imgMat, grayMat, Imgproc.COLOR_BGR2GRAY);
由于计算矩通常对二值图进行,因此首先将图像转换为灰度图。
• 二值化处理:
Imgproc.threshold(grayMat, binaryMat, 128, 255, Imgproc.THRESH_BINARY);
通过 threshold() 方法进行二值化处理,使目标区域清晰可见。
(2) 计算几何矩
Moments moments = Imgproc.moments(binaryMat, true);
• moments.get_m00():计算图像的面积(即目标区域的像素数)。
• moments.get_m10() 和 moments.get_m01():用于计算质心(Centroid) 。
• 质心计算公式:
double cx = moments.get_m10() / moments.get_m00();
double cy = moments.get_m01() / moments.get_m00();
System.out.println("质心坐标: (" + cx + ", " + cy + ")");
质心的计算对于形状分析、物体跟踪和图像处理非常重要。
• 绘制质心点:
Imgproc.circle(imgMat, new Point(cx, cy), 5, new Scalar(0, 0, 255), -1);
在图像上绘制一个红色的质心点,直观显示中心位置。
(3) 计算 Hu 不变矩
double[] huMoments = new double[7];
Imgproc.HuMoments(moments, huMoments);
• Hu 矩的特点:
• 具有 平移、缩放、旋转不变性,适用于形状匹配。
• 可以用于 模式识别,如 手写字符识别、目标分类 等。
• 打印 Hu 矩:
for (int i = 0; i < huMoments.length; i++) {
System.out.println("I" + (i + 1) + ": " + huMoments[i]);
}
4. 示例运行结果
如果输入的是一个白色物体的二值图像(黑色背景),输出示例如下:
质心坐标: (150.4, 180.7)
Hu 不变矩:
I1: 0.002314
I2: 5.6782e-06
I3: 3.0921e-11
I4: 1.3451e-12
I5: 2.7835e-19
I6: 5.4218e-16
I7: 3.1097e-20
同时,在 ImageView 中显示带有红色质心点的图像。
5. 总结
• 几何矩 可用于计算面积、质心、形状方向等信息。
• 中心矩 可消除平移影响,适用于位置无关的形状分析。
• Hu 不变矩 具有平移、旋转、缩放不变性,广泛用于模式识别和目标匹配。
• Android OpenCV 提供了 Imgproc.moments() 计算矩,并可直接计算 Hu 矩,非常适用于图像处理任务。
通过这个方法,我们可以在 Android OpenCV 中高效计算图像的矩,并应用到目标检测、形状匹配和图像分析等领域。🚀