Android OpenCV 边缘检测 Canny 的使用
程序员文章站
2024-01-28 09:56:34
...
先看下实现的效果图
下面看下代码使用
Canny(Mat image, Mat edges, double threshold1, double threshold2, int apertureSize, boolean L2gradient)
@param image 8-bit input image.
* @param edges output edge map; single channels 8-bit image, which has the same size as image .
* @param threshold1 first threshold for the hysteresis procedure.
* @param threshold2 second threshold for the hysteresis procedure.
* @param apertureSize aperture size for the Sobel operator.
* @param L2gradient a flag, indicating whether a more accurate \(L_2\) norm
* \(=\sqrt{(dI/dx)^2 + (dI/dy)^2}\) should be used to calculate the image gradient magnitude (
* L2gradient=true ), or whether the default \(L_1\) norm \(=|dI/dx|+|dI/dy|\) is enough (
* L2gradient=false )
第一个参数image:输入图像,单通道8位图像
第二个参数edges:输出边缘图像,需要和原图像有一样尺寸和类型
第三个参数threshold1:第一个滞后性阈值
第四个参数threshold2:第二个滞后性阈值 这个数值越大轮廓越少,
第五个参数apertureSize:表示应用sobel算子的孔径大小其有默认值3
第六个参数L2gradient:bool类型的L2gradient,一个计算图像梯度幅值的标识阈值1和阈值2中较小的用于边缘的连接,较大的用于控制强边缘的初始段。高低阈值比在2:1和3:1之间时最佳的
public class CanneyActivity extends AppCompatActivity {
private ImageView imageView;
private Bitmap bitmap;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.canney_activity_layout);
imageView = findViewById(R.id.img);
bitmap = ((BitmapDrawable) getResources().getDrawable(R.mipmap.photo)).getBitmap();
imageView.setImageBitmap(bitmap);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bitmap canneyBitmap = toCanneyByOpencv(bitmap);
imageView.setImageBitmap(canneyBitmap);
}
});
}
private Bitmap toCanneyByOpencv(Bitmap bitmap) {
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat);
Mat gray= new Mat();
// 转灰度图片
// Imgproc.cvtColor(mat, gray, Imgproc.COLOR_BGR2GRAY);
// 使用3x3的内核来降噪
// Imgproc.blur(mat, gray, new Size(3,3));
// 高斯降噪
// Imgproc.GaussianBlur(mat, gray, new Size(3,3),5,5);
//3 描绘边缘
Imgproc.Canny(mat, gray, 50, 200, 3, false);
Utils.matToBitmap(gray, bitmap);
return bitmap;
}
@Override
protected void onResume() {
super.onResume();
OpenCVLoader.initDebug();
}
}
xml 代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="边缘检测"/>
</LinearLayout>
可以修改threshold2 查看轮廓
public class CanneyActivity extends AppCompatActivity {
private ImageView imageView;
private Bitmap bitmap;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.canney_activity_layout);
imageView = findViewById(R.id.img);
bitmap = ((BitmapDrawable) getResources().getDrawable(R.mipmap.photo)).getBitmap();
imageView.setImageBitmap(bitmap);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bitmap canneyBitmap = toCanneyByOpencv(bitmap);
imageView.setImageBitmap(canneyBitmap);
}
});
}
private Bitmap toCanneyByOpencv(Bitmap bitmap) {
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat);
Mat gray= new Mat();
// 转灰度图片
// Imgproc.cvtColor(mat, gray, Imgproc.COLOR_BGR2GRAY);
// 使用3x3的内核来降噪
// Imgproc.blur(mat, gray, new Size(3,3));
// 高斯降噪
// Imgproc.GaussianBlur(mat, gray, new Size(3,3),5,5);
//3 描绘边缘
Imgproc.Canny(mat, gray, 3, 3, 3, false);
Utils.matToBitmap(gray, bitmap);
return bitmap;
}
@Override
protected void onResume() {
super.onResume();
OpenCVLoader.initDebug();
}
}
这个时候在看下效果图如下