gpt4 book ai didi

android - 在 Android 中使用 OpenCV 检测图像中的圆

转载 作者:搜寻专家 更新时间:2023-11-01 08:45:49 25 4
gpt4 key购买 nike

我正在开发一个 android 应用程序,其中我必须检测现有图像上的圆圈,从画廊浏览或从相机捕获。浏览/捕获的图像将显示在 ImageView 上。顺便说一句,我正在使用 OpenCVAndroid Library 并且我正确地编译了它。

对于我的 android 应用程序的任何帮助,我已经阅读了 C、C++ 或其他关于检测圆圈的内容,但我无法理解它,因为它适用于 android 的不同语言。

谢谢。

更新

好吧……我就是这样用的。

            if (requestCode == 1) { //Take Photo from Android Camera..

File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();

bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
bitmapOptions);

// bitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);



String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
outFile.flush();
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

/* convert bitmap to mat */
Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
CvType.CV_8UC1);
Mat grayMat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
CvType.CV_8UC1);

Utils.bitmapToMat(bitmap, mat);

/* convert to grayscale */
int colorChannels = (mat.channels() == 3) ? Imgproc.COLOR_BGR2GRAY
: ((mat.channels() == 4) ? Imgproc.COLOR_BGRA2GRAY : 1);

Imgproc.cvtColor(mat, grayMat, colorChannels);

/* reduce the noise so we avoid false circle detection */
Imgproc.GaussianBlur(grayMat, grayMat, new Size(9, 9), 2, 2);

// accumulator value
double dp = 1.2d;
// minimum distance between the center coordinates of detected circles in pixels
double minDist = 20;

// min and max radii (set these values as you desire)
int minRadius = 0, maxRadius = 0;

// param1 = gradient value used to handle edge detection
// param2 = Accumulator threshold value for the
// cv2.CV_HOUGH_GRADIENT method.
// The smaller the threshold is, the more circles will be
// detected (including false circles).
// The larger the threshold is, the more circles will
// potentially be returned.
double param1 = 70, param2 = 72;

/* create a Mat object to store the circles detected */
Mat circles = new Mat(bitmap.getWidth(),
bitmap.getHeight(), CvType.CV_8UC1);

/* find the circle in the image */
Imgproc.HoughCircles(grayMat, circles,
Imgproc.CV_HOUGH_GRADIENT, dp, minDist, param1,
param2, minRadius, maxRadius);

/* get the number of circles detected */
int numberOfCircles = (circles.rows() == 0) ? 0 : circles.cols();

/* draw the circles found on the image */
for (int i=0; i<numberOfCircles; i++) {


/* get the circle details, circleCoordinates[0, 1, 2] = (x,y,r)
* (x,y) are the coordinates of the circle's center*/
double[] circleCoordinates = circles.get(0, 0);


int x = (int) circleCoordinates[0], y = (int) circleCoordinates[1];

Point center = new Point(x, y);

int radius = (int) circleCoordinates[2];

/* circle's outline */
Core.circle(mat, center, radius, new Scalar(0,
255, 0), 4);

/* circle's center outline */
Core.rectangle(mat, new Point(x - 5, y - 5),
new Point(x + 5, y + 5),
new Scalar(0, 128, 255), -1);
}

/* convert back to bitmap */
Utils.matToBitmap(mat, bitmap);
viewImage.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}

}

我用上面的代码运行我的应用程序,我的 Android 手机在我用相机拍照后崩溃了,我在 logcat 中有这个错误:

          02-10 06:54:15.773    8914-8914/com.example.cloud.circle E/AndroidRuntime﹕ FATAL EXCEPTION: main

java.lang.UnsatisfiedLinkError: n_Mat
at org.opencv.core.Mat.n_Mat(Native Method)
at org.opencv.core.Mat.<init>(Mat.java:477)
at com.example.cloud.circle.Image.onActivityResult(Image.java:152)
at android.app.Activity.dispatchActivityResult(Activity.java:3908)
at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:2578)
at android.app.ActivityThread.access$2000(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:965)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)

请帮帮我。谢谢。

最佳答案

可以找到圆检测的详细解释herehere (尽管不是在 Java 中)。

我从上面提供的 2 个链接中收集了一个圆检测示例代码 fragment 。代码有注释,所以很容易理解。我假设图像位图 bitmap 已经有了你要分析的图像。

/* convert bitmap to mat */
Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
CvType.CV_8UC1);
Mat grayMat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
CvType.CV_8UC1);

Utils.bitmapToMat(bitmap, mat);

/* convert to grayscale */
int colorChannels = (mat.channels() == 3) ? Imgproc.COLOR_BGR2GRAY
: ((mat.channels() == 4) ? Imgproc.COLOR_BGRA2GRAY : 1);

Imgproc.cvtColor(mat, grayMat, colorChannels);

/* reduce the noise so we avoid false circle detection */
Imgproc.GaussianBlur(grayMat, grayMat, new Size(9, 9), 2, 2);

// accumulator value
double dp = 1.2d;
// minimum distance between the center coordinates of detected circles in pixels
double minDist = 100;

// min and max radii (set these values as you desire)
int minRadius = 0, maxRadius = 0;

// param1 = gradient value used to handle edge detection
// param2 = Accumulator threshold value for the
// cv2.CV_HOUGH_GRADIENT method.
// The smaller the threshold is, the more circles will be
// detected (including false circles).
// The larger the threshold is, the more circles will
// potentially be returned.
double param1 = 70, param2 = 72;

/* create a Mat object to store the circles detected */
Mat circles = new Mat(bitmap.getWidth(),
bitmap.getHeight(), CvType.CV_8UC1);

/* find the circle in the image */
Imgproc.HoughCircles(grayMat, circles,
Imgproc.CV_HOUGH_GRADIENT, dp, minDist, param1,
param2, minRadius, maxRadius);

/* get the number of circles detected */
int numberOfCircles = (circles.rows() == 0) ? 0 : circles.cols();

/* draw the circles found on the image */
for (int i=0; i<numberOfCircles; i++) {


/* get the circle details, circleCoordinates[0, 1, 2] = (x,y,r)
* (x,y) are the coordinates of the circle's center
*/
double[] circleCoordinates = circles.get(0, i);


int x = (int) circleCoordinates[0], y = (int) circleCoordinates[1];

Point center = new Point(x, y);

int radius = (int) circleCoordinates[2];

/* circle's outline */
Core.circle(mat, center, radius, new Scalar(0,
255, 0), 4);

/* circle's center outline */
Core.rectangle(mat, new Point(x - 5, y - 5),
new Point(x + 5, y + 5),
new Scalar(0, 128, 255), -1);
}

/* convert back to bitmap */
Utils.matToBitmap(mat, bitmap);

更新

为了防止 UnsatisfiedLinkError,在使用 OpenCV 库函数之前,请确保加载库文件,如下所示:

if (!OpenCVLoader.initDebug()) {
Log.e(TAG, "Cannot connect to OpenCV Manager");
}

关于android - 在 Android 中使用 OpenCV 检测图像中的圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28401343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com