账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    Android OpenCV 圆的检测
    47
    0

    当我在一张灰度图上通过opencv查找霍夫圆时能够找到圆,但是一旦对那个灰度图通过OpenCV进行二值化后则无法找到圆,以下为部分代码

     Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image_test);
            Mat srcMat=new Mat();
            Utils.bitmapToMat(bitmap,srcMat);
            Mat grayMat=new Mat();
            //转为灰度图像
            Imgproc.cvtColor(srcMat,grayMat,Imgproc.COLOR_RGB2GRAY);
            Mat binaryMat =new Mat();
            //二值化图像
            Imgproc.threshold(grayMat,binaryMat,40,255,Imgproc.THRESH_BINARY);
              //下面如果将参数 grayMat 换成 binaryMat后则无法找到圆
            Mat effectMat = OpenCvHelper.findEffectArea(grayMat, 5, 20, 5,
                    seekbarWidth.getProgress(),
                    seekbarHeight.getProgress(),
                    seekbarIntervalx.getProgress(),
                    seekbarIntervaly.getProgress());
            if (effectMat == null) {
                Toast.makeText(this, "无法找到有效区域", Toast.LENGTH_SHORT).show();
                return;
            }
            mImage.setImageBitmap(mat2Bitmap(effectMat));

    下面是OpencvHelper.findEffectArea()中查找圆的代码:

            Mat matchAnchorMat = new Mat();
             Imgproc.HoughCircles(mat, matchAnchorMat, Imgproc.CV_HOUGH_GRADIENT, 1, minDist, param1, param2, minRadius, maxRadius);
            int size = matchAnchorMat.cols();
            Log.w(TAG,"findCircle() 圆的个数:"+size);
            List<CircleInfo> pointList = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                double[] data = matchAnchorMat.get(0, i);
                CircleInfo circleInfo = new CircleInfo(data[0], data[1], data[2]);
                pointList.add(circleInfo);
            }
            return pointList;
    0
    打赏
    收藏
    点击回答
        全部回答
    • 共 0 条
    • 倚楼听雨. 普通会员 1楼

      在Android OpenCV中,圆的检测可以通过以下步骤实现:

      1. 加载库: 首先,需要在你的Android项目中添加OpenCV库,可以通过以下步骤在Gradle中进行:

      gradle dependencies { implementation 'org.opencv.android:opencv-android:4.1.0' }

      1. 准备图像: 在Android程序中,你需要获取一个图像文件,这可以通过Intent的data属性获取。例如:

      java Intent intent = new Intent(); intent.setData(Uri.parse("your_image_path")); startActivityForResult(intent, YOUR_REQUEST_CODE);

      在上述代码中,your_image_path是你的图像文件路径,YOUR_REQUEST_CODE是你的请求代码,你可以根据你的需求修改为不同的值。

      1. 创建Camera对象: 为了检测图像中的圆,我们需要创建一个Camera对象。在AndroidManifest.xml文件中,你可以添加以下权限:

      xml <uses-permission android:name="android.permission.CAMERA" />

      然后,在你的Activity中创建一个CameraCaptureSession对象,这个对象包含了相机的CameraDevice和CameraParameters。以下是一个示例:

      ```java private CameraCaptureSession mSession;

      public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

      // 从Intent中获取相机设备和参数
      CameraDevice cameraDevice = CameraDevice.getCameraDeviceById(R.drawable.camera_id);
      CameraParameters cameraParameters = cameraDevice.getParameters();
      boolean isVideo = cameraParameters.isVideo;
      
      // 创建CameraCaptureSession
      mSession = new CameraCaptureSession.Builder()
              .setCamera(cameraDevice)
              .setCaptureSessionType(CameraCaptureSession.CAPTURE_VIDEO_OUTPUT)
              .build();
      
      // 设置预览器和窗口大小
      mSession.setPreviewDisplay(getWindow().getDecorView());
      int width = previewWidth;
      int height = previewHeight;
      if (isVideo) {
          mSession.setVideoSize(width, height);
      }
      
      // 添加相机捕获器
      mSession.addCaptureListener(new CameraCaptureSession.StateChangeCallback() {
          @Override
          public void onOpened(CameraCaptureSession session) {
              super.onOpened(session);
              // 当设备被打开时,设置视频输出设备
              if (isVideo) {
                  mSession.setVideoStream(session.get输出Stream());
              }
          }
      
          @Override
          public void onClosed(CameraCaptureSession session) {
              super.onClosed(session);
              // 当设备关闭时,释放视频输出设备
              if (isVideo) {
                  mSession.releaseOutputStream(session.getOutputStream());
              }
          }
      
          @Override
          public void onStillImageAvailable(CameraCaptureSession session, String path) {
              super.onStillImageAvailable(session, path);
              // 当相机返回图像时,保存到文件
              try {
                  FileOutputStream fos = openFileOutput("image.jpg", MODE_APPEND);
                  byte[] buffer = new byte[1024];
                  int length;
                  while ((length = mSession.read(buffer)) > 0) {
                      fos.write(buffer, 0, length);
                  }
                  fos.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      });
      
      // 开始捕获
      mSession.start();
      

      } ```

      1. 开始或暂停捕获: 你可以使用start()方法开始捕获,或者使用pause()方法暂停捕获。例如:

      ```java // 开始捕获 mSession.start();

      // 停止捕获 mSession.pause(); ```

      1. 检测圆: 当相机捕获到图像时,OpenCV会将每个像素的颜色值转换为红、绿、蓝(RGB)值,然后使用欧几里得距离算法(欧几里得距离,Euclidean distance)来检测圆。以下是一个简单的示例:

      ```java // 检测圆 Mat grayImage = new Mat(); grayImage.convertTo("gray_image.jpg", GrayType.CV_8UC1); Mat circleImage = new Mat(); CircleDetector circleDetector = new CircleDetector(); circleDetector.detect(grayImage);

      // 显示圆 for (Circle circle : circleDetector.get circles()) { int x = circle.getCenter().x; int y = circle.getCenter().y; int radius = circle.getRadius(); Imgproc.circle(circleImage, new Point(x, y), radius, Scalar(255, 255, 255), 2); }

      // 保存圆到文件 try { FileOutputStream fos = openFileOutput("circle.jpg", MODE_APPEND); circleImage.write(fos); fos.close(); } catch (IOException e) { e.printStackTrace(); } ```

      在这个示例中,gray_image.jpg是你获取的图像文件名,circle.jpg是你想要保存圆到的文件名。在检测圆时,我们首先将图像转换为灰度图像,然后使用CircleDetector类检测圆形。然后,我们使用OpenCV的circle()函数绘制圆,并将圆的中心坐标和半径写入到保存的文件中。

      注意:这个示例使用了OpenCV的CircleDetector类,这是一个高精度的圆检测器,适用于高质量的图像。如果你的图像质量较低,你可能需要使用其他方法,例如CircleDetectorOpenCV或CircleDetectorKMeans。此外,这个示例中假设你的图像是以红、绿、蓝(RGB)颜色模式表示的,如果你的图像以其他颜色模式表示,你可能需要调整CircleDetector.detect()函数的参数。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部