一、显示效果展示
二、OpenCV 4.5.0
OpenCV 4.5.0是OpenCV(Open Source Computer Vision Library,开源计算机视觉库)的一个重要更新版本,该版本在多个方面进行了优化和新增了多项功能。
三、ONNX模型
ONNX(Open Neural Network Exchange)模型是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。它允许不同的深度学习框架(如PyTorch、TensorFlow、MXNet等)之间交换和共享模型,使得模型可以在不同平台和工具上进行部署和推理。
四、OpenCV加载onnx模型进行前向推理实现识别扑克牌识别
java
//统计预测的结果
private int[] number_class=new int[54];
public Bitmap detection(Bitmap bp){
Canvas can=new Canvas();
Paint p=new Paint();
android.graphics.Bitmap.Config bitmapConfig = bp.getConfig();
bp = bp.copy(bitmapConfig, true);
can=new Canvas(bp);
p.setAntiAlias(true);
//不填充,默认填充
p.setStyle(Paint.Style.STROKE);
//设置线条宽度
p.setStrokeWidth(5);
//设置颜色
p.setColor(0xFF33FFFF);
p.setTextAlign(Paint.Align.LEFT);
p.setTextSize(50);
Mat blob = Dnn.blobFromImage(src, IN_SCALE_FACTOR,
new Size(IN_WIDTH, IN_HEIGHT),
new Scalar(MEAN_VAL, MEAN_VAL, MEAN_VAL), false);
net.setInput(blob);
blob.release();
//获取输出层的名字
List<String> outnames=net.getUnconnectedOutLayersNames();
// Log.i("aa",String.valueOf(outnames));
//创建输出矩阵集合
List<Mat> detections = new ArrayList<Mat>();
net.forward(detections,outnames);
//获取输出的盒子和置信度
Mat scores=detections.get(0);
Mat boxes= detections.get(1);
scores= scores.reshape(1,3000).colRange(1,55);
boxes= boxes.reshape(1,3000);
Size ss=scores.size();
// Log.i("aa",String.valueOf(scores));
// Log.i("aa",String.valueOf(boxes));
List<Rect2d> rect2dList=new ArrayList<>();//box信息
List<Float> confList=new ArrayList<>();//置信度
List<Integer> objIndexList=new ArrayList<>();//对象类别索引
for(int i=0; i<scores.rows();i++){
Mat one_row=scores.rowRange(i,i+1);
Core.MinMaxLocResult max_index=Core.minMaxLoc(one_row);
double max_value=max_index.maxVal;
Point location=max_index.maxLoc;
if(max_value>0.4){
confList.add((float) max_value);
objIndexList.add((int)location.x);
Mat box_one=boxes.rowRange(i,i+1);
float[] aa=new float[4];
box_one.get(0,0,aa);
double x1=aa[0];
double y1=aa[1];
double x2=aa[2];
double y2=aa[3];
rect2dList.add(new Rect2d(x1,y1,x2,y2));
}
}
//去重
//去重后的索引值
MatOfInt index=new MatOfInt();
//转换box的结果集
MatOfRect2d boxe=new MatOfRect2d(rect2dList.toArray(new Rect2d[0]));
//转换置信度结果集
float[] confArr=new float[confList.size()];
for(int j=0;j<confList.size();j++){
confArr[j]=confList.get(j);
}
MatOfFloat con=new MatOfFloat(confArr);
//使用nms去重
Dnn.NMSBoxes(boxe,con,0.4f,0.45f,index);
if (index.empty()){
return bp;
}
//画框
int[] ints=index.toArray();
for(int x:ints){
// Log.i("aa",String.valueOf(x));
double[] aa=new double[4];
boxe.get(x,0,aa);
//Log.i("aa",String.valueOf(aa[0]));
//Imgproc.rectangle(src,new Point(aa[0]*src.width(),aa[1]*src.height()-70),new Point(aa[2]*src.width()+200,aa[1]*src.height()),new Scalar(255,255,255),-1);
//Imgproc.rectangle(src,new Point(aa[0]*src.width(),aa[1]*src.height()),new Point(aa[2]*src.width(),aa[3]*src.height()),new Scalar(255,255,0),10);
//Imgproc.putText(src,""+classNames[objIndexList.get(x)]+":"+confList.get(x),new Point(aa[0]*src.width(),aa[1]*src.height()),Imgproc.FONT_HERSHEY_SIMPLEX, 3, new Scalar(0, 0, 0));
//画框
can.drawRect((float) aa[0]*src.width(),(float) aa[1]*src.height(),(float)aa[2]*src.width(),(float)aa[3]*src.height(),p);
//绘制填充框
p.setStyle(Paint.Style.FILL);
p.setColor(0xFFFFCC00);
can.drawRect((float) aa[0]*src.width(),(float) aa[1]*src.height()-60,(float)aa[2]*src.width()+150,(float)aa[1]*src.height(),p);
//写字
p.setColor(0xFFFF0000);
can.drawText(classNames[objIndexList.get(x)]+": "+String.format("%.3f", confList.get(x)),(float)aa[0]*src.width(),(float) aa[1]*src.height()-10,p);
p.setStyle(Paint.Style.STROKE);
p.setColor(0xFF33FFFF);
//统计类别信息
number_class[objIndexList.get(x)]+=1;
}
五、完整源码下载:
Card.zip: https://url83.ctfile.com/f/45573183-1373015108-43a4dd?p=7526 (访问密码: 7526)