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

2024-01-27

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

对我的 Android 应用程序有任何帮助吗,我已经阅读了 C、C++ 等来检测圆圈,但我无法理解它,因为它的 Android 语言不同。

Thanks.

Update

好吧...我就是这么用的。

            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)

请帮我。谢谢。


圆检测的详细解释可以参见here http://www.pyimagesearch.com/2014/07/21/detecting-circles-images-using-opencv-hough-circles/ and here http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html(尽管不是在 Java 中)。

我在下面提供了一个用于圆形检测的示例代码片段,该代码片段是从我上面提供的 2 个链接中获取的。代码有注释,所以很容易理解。我假设图像位图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);

Update

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

if (!OpenCVLoader.initDebug()) {
    Log.e(TAG, "Cannot connect to OpenCV Manager");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Android 中使用 OpenCV 检测图像中的圆圈 的相关文章

  • GCM 向主题发送消息:TOO_MANY_TOPICS 错误

    以前 GCM 每个应用程序有 100 万个主题订阅的限制 我发现他们现在已经取消了这一限制 基于发布 订阅模型 主题消息支持 每个应用程序无限订阅 https developers google com cloud messaging to
  • Android第一次动画不流畅

    我正在尝试一个动画将 imageView 从屏幕底部滑动到屏幕中心 但是当我第一次执行此动画时 它不平滑 但当第二次执行动画时 它是正常且平滑的 我几乎尝试了所有方法 但无法解决我的问题 这是我的动画文件
  • Android 应用程序在后台运行时保存数据

    目前我正在开发 xmmp 客户端 当应用程序位于前台时 该客户端工作得很好 但由于事实上 当应用程序处于后台时 我在 Application 类中保存了大量数据 复杂的 ArrayList 字符串和布尔值作为公共静态 每个字段都被垃圾收集
  • 导航组件重复 NavArgs 的问题

    我有一个片段 class SomeFragment private val args by navArgs
  • 与 Admob 广告单元 ID 混淆

    我跟着tutorial https developers google com admob android quick start在我的应用程序中创建广告横幅 到目前为止 这有效 我可以看到测试广告 但是 本教程指示我在两个不同的位置使用两
  • 如何从 SQLite 获取记录总数

    我正在尝试从 Sqlite DB 获取行的总数 以下是我想要做的代码片段 我不知道我在这里做错了什么 public static int getTotalCount Context context Cursor c null try c g
  • 菜单未显示在应用程序中

    由于某种原因 我的操作菜单在我的 Android Studio 应用程序中消失了 我正在按照教程学习如何创建 Android 应用程序 但最终遇到了这个问题 我正在使用 atm 的教程 http www raywenderlich com
  • Delphi XE7 Android 全屏(隐藏软键)

    如何在XE7中全屏显示 隐藏顶部 标题 和底部 软键 工具栏 在 XE6 中 我可以通过在应用程序部分写入来调整 AndroidManifest 以使我的应用程序全屏显示并且没有操作栏 android theme android style
  • 在 Google Analytics 中跟踪应用程序版本

    我正在使用谷歌分析模块 https marketplace appcelerator com apps 5081 2014113336 https marketplace appcelerator com apps 5081 2014113
  • 在 Android 中使用 DataOutputStream 在 POST 正文中发送特殊字符 (ë ä ï)

    我目前正在开发一个具有大量服务器端通信的 Android 应用程序 昨天 我收到一份错误报告 称用户无法发送 简单 特殊字符 例如 我搜索过但没有找到任何有用的东西 可能重复 没有答案 https stackoverflow com que
  • 获取 AlarmManager 中活动的 PendingIntents 列表

    我有办法获取活动列表PendingIntent在设备中 我开始工作AlarmManager我想看看我的PendingIntents 已正确创建和删除 也很高兴看到其他什么PendingIntent在那里 只是为了看看某些应用程序是否正在做一
  • 在 Visual Studio C++ 2008 中包含 dll

    有没有办法将 dll 包含在项目中 这样我就不必在编译后将这些 dll 与可执行文件放在同一文件夹中 这样我就可以用它们编译我的项目 这是否有可能 如果是 有人可以指导我 我的项目是一个 opencv 项目 有很多 dll 我必须包含在文件
  • Android Webview 图像未加载

    我制作了一个简单的应用程序WebView 但有些图片无法加载 正确 在我的电脑上 错误 在模拟器中 Correct 错误 没有横幅 于是我用Chrome debug进行调试 发现我的代码被改变了 我不添加像noscript or style
  • Android 设备上的静默安装

    我已经接受了一段时间了 在 Android 上静默安装应用程序是不可能的 也就是说 让程序安装捆绑为 APK 的应用程序 而不提供标准操作系统安装提示并完成应用程序安装程序活动 但现在我已经拿到了 Appbrain 快速网络安装程序的副本
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • Android:有没有办法以毫安为单位获取设备的电池容量?

    我想获取设备的电池容量来进行一些电池消耗计算 是否可以以某种方式获取它 例如 三星 Galaxy Note 2 的电池容量为 3100mAh 谢谢你的帮助 知道了 在 SDK 中无法直接找到任何内容 但可以使用反射来完成 这是工作代码 pu
  • Android 如何聚焦当前位置

    您好 我有一个 Android 应用程序 可以在谷歌地图上找到您的位置 但是当我启动该应用程序时 它从非洲开始 而不是在我当前的城市 国家 位置等 我已经在developer android com上检查了信息与位置问题有关 但问题仍然存在
  • 用于推送通知的设备令牌

    我正在实施推送通知服务 我需要创建一个数据库来存储 4 个移动平台的所有设备令牌 我想根据他们的平台 iOS Android BlackBerry WP7 来组织它们 但是有什么方法可以区分平台 这样如果我只想向 Android 用户发送消
  • 如何删除因 Google Fitness API 7.5.0 添加的权限

    将我的 play services fitness api 从 7 0 0 更新到 7 5 0 后 我注意到当我将新版本上传到 PlayStore 时 它 告诉我正在添加一个新权限和 2 个新功能 我没有这样做 有没有搞错 在做了一些研究来
  • 找到 Android 浏览器中使用的 webkit 版本?

    有没有办法知道某些特定手机上的 Android 浏览器使用的是哪个版本的 webkit 软件 如果有一个您可以浏览以获取该信息的 URL 那就太好了 但任何其他方式也很好 如果你知道 webkit 版本 你就知道 html5 支持多少 至少

随机推荐

  • Bootstrap colorpicker 基本示例不起作用

    我想为 bootstrap 使用颜色选择器插件 https farbelous io bootstrap colorpicker index html https farbelous io bootstrap colorpicker ind
  • 迭代c中的结构体

    我正在编写一个与此代码类似的单元测试 并且我正在尝试在设置值时测试它们 以便我知道发生了什么 当我运行以下代码时 我不明白为什么 ptr 值没有设置为 1 相反 当我运行它时 它给出的输出为 10 64 0 0 任何解释或建议将不胜感激 i
  • VBS 中的 MSGbox 根据变量值进行更新

    只是想知道我如何拥有一个 MSgbox 来显示不断变化的变量值 基本上 一个数字每次循环时都会添加一个 我想在不必打开一百万个窗口的 MSGbox 中显示它 解决方法是使用PopUp Set objShell WScript CreateO
  • 如何将值查询集的值追加到数组?

    我的观点 py from django db models import Count def test1 request states Loksabha objects values state distinct state terms L
  • Ionic 导航栏:标题未在 Android 设备上居中

    我对 Ionic 很陌生 但我已经喜欢它了 我想用nav bar所以我实现了以下index html
  • 编写不使用循环索引的 for 循环的 Pythonic 方法[重复]

    这个问题在这里已经有答案了 这与以下代码有关 该代码使用 for 循环生成一系列随机偏移量以供程序中其他地方使用 该 for 循环的索引未使用 这导致 Eclipse PyDev 将 有问题的 代码突出显示为警告 def RandomSam
  • 如何在 Actionscript 3 中将十六进制转换为十进制?

    如何在 Actionscript3 中将十六进制 字符串 转换为十进制 int Number int and uint类有toString 接受的方法radix作为参数 radix指定用于数字到字符串转换的数字基数 从 2 到 36 如果不
  • 如何从 DOM 中删除 element.nativeElement?

    我尝试了这样的方法 ViewChild draggable private draggableElement ElementRef this draggableElement nativeElement remove HTML div Bl
  • MVC3 ajax 将多个复选框值发送到控制器

    我正在尝试使用 MVC3 来完成以下任务 我有一个包含多个值的表 使用ajax我希望能够选择作为表一部分的删除复选框 对于任意数量的行 使用ajax将结果发布到控制器进行处理 我目前遇到的问题是我无法让控制器接受来自 ajax post 的
  • Websocket 因 1006 错误而断开连接,无原因

    我正在我的网页游戏中记录断开连接 似乎 75 的会话因代码 1001 正常 而断开连接 25 的会话因代码 1006 错误 而断开连接 https www rfc editor org rfc rfc6455 https www rfc e
  • 五个不同的 GAE 站点可以共享一个公共数据存储吗?

    除了特定站点的数据存储之外 您是否还可以在所有网站之间共享一个数据存储 比如连接到与主 MySQL 数据库不同的 MySQL 数据库 并不真地 两种解决方法 使用同一应用程序的五个 版本 而不是五个不同的应用程序 他们将共享相同的数据存储
  • 将 python django 项目 1.3 升级到 1.5

    目前我有一个使用 django 版本 1 3 的 python 项目在 Mountain Lion OS 上运行 现在我想将其升级到 django 1 5 但是当我把它放在尝试做的时候python manage py runserver我收
  • 具有 SFINAE 虚拟参数的不明确模板

    考虑一种需要验证类型的情况T与另一个模板g 可能是一些enable if表达式 例如 在另一个模板的虚拟参数内 如下所示 template
  • ConnectionString 属性尚未初始化

    我查看了不同论坛上的很多帖子 其他人也收到了同样的错误 大多数人表示他们没有正确引用 web config 文件中的连接字符串 或者他们在设置连接字符串之前尝试打开连接 好吧 如果对我来说是这种情况 那么它如何在两个不同的系统上工作 但在第
  • 如何在 CertCreate 自签名证书函数中指定密钥大小

    我正在使用该功能证书创建自签名证书 https msdn microsoft com en us library windows desktop aa376039 v vs 85 aspx生成证书 我需要指定密钥大小2048 我不知道如何提
  • javascript按索引号进行字符串分配怪癖

    a 12345 a 2 3 a 2 9 console log a gt 12345 到底是怎么回事 这个怪癖导致我痛苦地调试了1个小时 如何以明智的方式避免这种情况 不能使用方括号重写字符串中的各个字符 仅 getter 即读取 访问可用
  • Github 操作 `on` 中没有定义事件触发器

    我创建了一个管道 我想在每次推送任何分支时触发 有我的default yml name default on push branches jobs build runs on macOS latest steps uses actions
  • 模板类的 typedef?

    是否有可能typedef使用模板的长类型 例如 template
  • 反应本机要求不适用于图像源

    给出下面的代码 反应本机抱怨 Requiring unknown module images Foo png If you are sure the module is there try restarting the packager o
  • 在 Android 中使用 OpenCV 检测图像中的圆圈

    我正在开发一个安卓应用程序其中我必须检测现有图像上的圆圈 从图库浏览或从相机捕获 浏览 捕获的图像将显示在 ImageView 上 顺便说一句 我正在使用OpenCV Android 库我正确地编译了它 对我的 Android 应用程序有任