最近在学习OpenCV+Android图像识别课程,跟着B站课程做了一个Demo.记录下来,这个Demo的主要功能是针对如下图所示的图形信息来进行切割,颜色识别,轮廓识别,以及计数。
1.首先是建立一个activi_main.xml(代码略)
2.MainActivity.java
(1)切割
效果: 裁剪右下角区域
代码:
btnQG.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Rect rect = new Rect(260,185,480,290);
dstMat = new Mat(srcMat,rect);//从原图上切割一块下来
bitmap=Bitmap.createBitmap(dstMat.width(),dstMat.height(), Bitmap.Config.ARGB_8888);
Imgproc.cvtColor(dstMat,dstMat,Imgproc.COLOR_BGR2RGB);
Utils.matToBitmap(dstMat,bitmap);
iv1.setImageBitmap(bitmap);
}
});
(2)颜色
效果:识别指定颜色 这里演示识别绿色
代码:
btnYS.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hsvMat= new Mat();
Imgproc.cvtColor(dstMat,hsvMat,Imgproc.COLOR_RGB2HSV);
Core.inRange(hsvMat,new Scalar(45,90,90),new Scalar(75,255,255),hsvMat);
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(3,3));
/*
*这个函数的第一个参数表示内核的形状,有三种形状可以选择。
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;
* 第二和第三个参数分别是内核的尺寸以及锚点的位置
* 对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心点
*/
Imgproc.morphologyEx(hsvMat,hsvMat,Imgproc.MORPH_OPEN,kernel);//执行开运算 消除背景上的白色噪点
Imgproc.morphologyEx(hsvMat,hsvMat,Imgproc.MORPH_CLOSE,kernel);//执行闭运算 消除白色上的黑色噪点
Utils.matToBitmap(hsvMat,bitmap);//把Mat转换为Bitmap
iv1.setImageBitmap(bitmap);//显示
}
});
3.轮廓:将指定颜色图形 轮廓识别出来
效果:
代码:
btnLK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Mat outMat = new Mat();
Imgproc.findContours(hsvMat,contours,outMat,Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_SIMPLE);
contoursCounts = contours.size();
//System.out.println("轮廓的数量:"+contoursCounts);
Imgproc.drawContours(dstMat,contours,-1,new Scalar(255,0,0),4);
Utils.matToBitmap(dstMat,bitmap);
iv1.setImageBitmap(bitmap);
}
});
4.形状
效果:统计该颜色下图片中各种颜色图形的数目
代码:
btnXZ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MatOfPoint2f contour2f;
double epsilon;
MatOfPoint2f approxCurve;
int tri=0,rect=0,circle=0;
for(int i=0;i<contoursCounts;i++) {
if (Imgproc.contourArea(contours.get(i)) > 10) {
//开闭运算后还可能存在一些相对较大(其实相对正常的图形较小)的噪点被识别为图形,所以可以采用面积识别法来进一步去除咋点
contour2f = new MatOfPoint2f(contours.get(i).toArray());//从集合contours取出第一个形状的所有位置信息 contour2f是一个二维数组 存储(x,y);
epsilon = 0.04 * Imgproc.arcLength(contour2f, true); //ture 是闭合曲线 多边形拟合的阈值
approxCurve = new MatOfPoint2f();//新建一个数组来存放多边形拟合后的顶点集合
Imgproc.approxPolyDP(contour2f, approxCurve, epsilon, true);//执行多边形拟合
System.out.println(approxCurve.rows());
if (approxCurve.rows() == 3) {
tri++;
} else if (approxCurve.rows() == 4) {
rect++;
} else if (approxCurve.rows() >= 5) {
circle++;
}
}
}
tv1.setText("轮廓:"+contoursCounts+"\n圆形:"+circle+"\n"+"三角:"+tri+"\n"+"矩形:"+rect);
}
});