- 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 条
- 全部回答
-
倚楼听雨. 普通会员 1楼
在Android OpenCV中,圆的检测可以通过以下步骤实现:
- 加载库: 首先,需要在你的Android项目中添加OpenCV库,可以通过以下步骤在Gradle中进行:
gradle dependencies { implementation 'org.opencv.android:opencv-android:4.1.0' }- 准备图像:
在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是你的请求代码,你可以根据你的需求修改为不同的值。- 创建
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();} ```
- 开始或暂停捕获:
你可以使用
start()方法开始捕获,或者使用pause()方法暂停捕获。例如:
```java // 开始捕获 mSession.start();
// 停止捕获 mSession.pause(); ```
- 检测圆: 当相机捕获到图像时,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()函数的参数。
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部
