手机AIDE使用OpenCV



需要使用OpenCV.jar和so文件

android 复制代码
package com.example.application;

import android.app.Activity;
import android.os.Bundle;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.view.View;
import java.util.ArrayList;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Queue;
import android.graphics.Color;
import java.util.LinkedList;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.android.Utils;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.MatOfPoint;
import java.util.List;
import org.opencv.core.Scalar;
import org.opencv.core.Core;


public class MainActivity extends Activity {
    private huabu hb;
	private Bitmap bitmap;
	static {
		// 加载OpenCV的.so库(库名与文件前缀一致,libopencv_java4.so对应"opencv_java4")
		System.loadLibrary("opencv_java4");
	}
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        hb = findViewById(R.id.huabu);
		if (!OpenCVLoader.initDebug()) {
			Toast.makeText(this, "OpenCV初始化失败", Toast.LENGTH_SHORT).show();
		}
		String str="/storage/emulated/0/脚本/Aj图片/screenshot_1759871209890.png";
		bitmap = BitmapFactory.decodeFile(str);
	}
	public void huiduhua(View v) {
		processImage();
	}
	private void processImage() {
		// 这里假设你要处理的图片在手机存储的指定路径,替换为实际图片路径
		if (bitmap == null) {
			Toast.makeText(this, "无法读取图片", Toast.LENGTH_SHORT).show();
			return;
		}
		 Mat mat = new Mat();
		 Utils.bitmapToMat(bitmap, mat);
		 Mat grayMat = new Mat();
		 Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_BGR2GRAY);
		 Bitmap grayBitmap = Bitmap.createBitmap(grayMat.cols(), grayMat.rows(), Bitmap.Config.ARGB_8888);
		 Utils.matToBitmap(grayMat, grayBitmap);
		 hb.setbittmap(grayBitmap);
	}
	public void hualunkuo(View v) {
	    //boolean a=colors.isSimilar("#000000", "#000010", 25);
		detectBlackFonts();
	}
	// 识别黑色字体的核心方法
	private void detectBlackFonts() {
		Bitmap originalBitmap = this.bitmap;
		if (originalBitmap == null) {
			Toast.makeText(this, "图片读取失败", Toast.LENGTH_SHORT).show();
			return;
		}

		Mat srcMat = new Mat();
		Utils.bitmapToMat(originalBitmap, srcMat);
		// 处理透明通道
		if (srcMat.channels() == 4) {
			Imgproc.cvtColor(srcMat, srcMat, Imgproc.COLOR_RGBA2BGR);
		}

		// 转为灰度图
		Mat grayMat = new Mat();
		Imgproc.cvtColor(srcMat, grayMat, Imgproc.COLOR_BGR2GRAY);

		// 阈值化(突出黑色字体)
		Mat binaryMat = new Mat();
		Imgproc.threshold(grayMat, binaryMat, 150, 255, Imgproc.THRESH_BINARY_INV);

		// 形态学操作:连接笔画
		Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new org.opencv.core.Size(4, 5));
		Imgproc.dilate(binaryMat, binaryMat, kernel);
		Imgproc.erode(binaryMat, binaryMat, kernel);

		// 提取所有轮廓
		List<MatOfPoint> contours = new ArrayList<>();
		Mat hierarchy = new Mat();
		Imgproc.findContours(binaryMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

		// 过滤有效轮廓并绘制边界矩形
		Scalar red = new Scalar(0, 0, 255); // 红色矩形
		for (MatOfPoint contour : contours) {
			// 1. 计算轮廓面积,过滤过小轮廓
			double area = Imgproc.contourArea(contour);
			if (area < 50) {
				contour.release();
				continue;
			}

			// 2. 获取轮廓的边界矩形(左上角和右下角坐标)
			org.opencv.core.Rect rect = Imgproc.boundingRect(contour);
			int width = rect.width;
			int height = rect.height;

			// 3. 过滤宽高比异常的矩形
			if (width == 0 || height == 0) {
				contour.release();
				continue;
			}
			double ratio = (double) width / height;
			if (ratio < 0.2 || ratio > 3.2) {
				contour.release();
				continue;
			}

			// 4. 绘制边界矩形(左上角(x1,y1),右下角(x2,y2))
			Imgproc.rectangle(
				srcMat,
				new org.opencv.core.Point(rect.x, rect.y), // 左上角坐标
				new org.opencv.core.Point(rect.x + width, rect.y + height), // 右下角坐标
				red, // 颜色
				2 // 线宽
			);

			contour.release(); // 及时释放资源
		}
		Toast.makeText(this, "完成"+contours.size(), 0).show();
		// 转换为Bitmap显示
		Mat resultMat = new Mat();
		Imgproc.cvtColor(srcMat, resultMat, Imgproc.COLOR_BGR2RGBA);
		Bitmap resultBitmap = Bitmap.createBitmap(resultMat.cols(), resultMat.rows(), Bitmap.Config.ARGB_8888);
		Utils.matToBitmap(resultMat, resultBitmap);
		hb.setbittmap(resultBitmap);

		// 释放剩余资源
		srcMat.release();
		grayMat.release();
		binaryMat.release();
		hierarchy.release();
		kernel.release();
		resultMat.release();
	}
	
	
	
	private void log(Exception e) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		e.printStackTrace(new PrintStream(baos));
		String str = baos.toString();
		log(str);
	}
	public Boolean log(String strcontent) {
		try {
			strcontent += "\n";
			String filePath="/sdcard/log.txt";
			File file=new File(filePath);//路径
			if (!file.exists()) {
				file.getParentFile().mkdirs();
				file.createNewFile();//创建txt文件
			}
			RandomAccessFile raf=new RandomAccessFile(file, "rwd");
			raf.seek(file.length());
			raf.write(strcontent.getBytes());
			raf.close();
			return true;
		} catch (Exception e) {
		}
		return false;
	}
}
相关推荐
whatever who cares19 分钟前
android/java中gson的用法
android·java·开发语言
用户02738518402628 分钟前
【Android】活动的正/异常生命周期和启动模式、标志位详解
android
nono牛2 小时前
MTK平台详解`adb devices`输出的序列号组成
android·linux·adb·智能手机
zhangphil2 小时前
Android通过SQL查询trace分析进程启动线程总数量
android
下位子2 小时前
『OpenGL学习滤镜相机』- Day3: 着色器基础 - GLSL 语言
android·opengl
bqliang2 小时前
Jetpack Navigation 3:领航未来
android·android studio·android jetpack
云存储小天使3 小时前
安卓蛙、苹果蛙为什么难互通?
android
陈大头铃儿响叮当5 小时前
Android Studio升级后,Flutter运行android设备报错
android·flutter·android studio
勤劳打代码5 小时前
isar_flutter_libs 引发 Namespace not specified
android·flutter·groovy
奔跑吧 android6 小时前
【android bluetooth 协议分析 18】【PBAP详解 2】【车机为何不显示电话号码为空的联系人信息】
android·蓝牙电话·hfp·pbap·电话簿