整个项目路径
https://download.youkuaiyun.com/download/Aaron121314/12291921
-------------------------------------------------------
使用opencv 来判断屏幕是否有坏点。
流程是这样的,先对着测试的手机屏幕拍照,然后剪切照片,把要检测的区域给截取出来,然后用Core.inRange 分析图片的每个像素的颜色,如果颜色在给定范围内就返回255 白色,不在就返回0黑色,最后生成一个新的Mat图片,一个黑白图片,最后我们去判断这个黑白图片,如果全是白色,说明没有坏点,给定的图片颜色都在给定颜色范围内,是用检测轮廓的方法来检测的,如果没有轮廓,就说明是都是白色,如果有黑点就会检测到轮廓,就说明有坏点。
截图
+ 点击选中要检测的图片资源
smin vmin是用来控制要检测颜色的深浅,默认可以不填。什么是hsv,去百度hsv颜色
x y width height 对图片资源进行剪切的范围
下拉列表,选择要检测的颜色
配置完成,点击button开始检测。检测结果会显示在右边的图片,同时会把不在范围内的颜色标记出来。这里检测蓝色,图片上有一些黑色的点,所以被标记出来了。
检测的原图
-------------------------------------------------------------------------------------
主要代码:
颜色判断,返回一个黑白的mat图片,分析图片的每个像素的颜色,如果颜色在给定范围内就返回255 白色,不在就返回0黑色
private Mat analyseColor( Mat src ) {
String color= (String) spinner.getSelectedItem();
if(color.equals( "Red" )){
hmin=HSV_Range[2][0];
smin=HSV_Range[2][2];
vmin=HSV_Range[2][4];
hmax=HSV_Range[2][1];
smax=HSV_Range[2][3];
vmax=HSV_Range[2][5];
}else if (color.equals( "Green" )){
hmin=HSV_Range[3][0];
smin=HSV_Range[3][2];
vmin=HSV_Range[3][4];
hmax=HSV_Range[3][1];
smax=HSV_Range[3][3];
vmax=HSV_Range[3][5];
}else if (color.equals( "Blue" )){
hmin=HSV_Range[4][0];
smin=HSV_Range[4][2];
vmin=HSV_Range[4][4];
hmax=HSV_Range[4][1];
smax=HSV_Range[4][3];
vmax=HSV_Range[4][5];
}else if (color.equals( "Black" )){
hmin=HSV_Range[0][0];
smin=HSV_Range[0][2];
vmin=HSV_Range[0][4];
hmax=HSV_Range[0][1];
smax=HSV_Range[0][3];
vmax=HSV_Range[0][5];
}else if (color.equals( "White" )){
hmin=HSV_Range[1][0];
smin=HSV_Range[1][2];
vmin=HSV_Range[1][4];
hmax=HSV_Range[1][1];
smax=HSV_Range[1][3];
vmax=HSV_Range[1][5];
}
if(!v.getText().toString().isEmpty()){
vmin=Integer.valueOf( v.getText().toString() );
}
if(!s.getText().toString().isEmpty()){
smin=Integer.valueOf( s.getText().toString() );
}
Mat hsv = new Mat();
Imgproc.cvtColor( src, hsv, Imgproc.COLOR_RGBA2BGR );
Imgproc.cvtColor( hsv, hsv, Imgproc.COLOR_BGR2HSV );
Mat r = new Mat();
Core.inRange( hsv, new Scalar( hmin, smin, vmin ),
new Scalar( hmax, smax, vmax), r );
return r;
}
判断是否有坏点(轮廓)
private void getPoints(Mat src){
Mat hierarchy=new Mat( );
Mat edge=new Mat( );
Imgproc.Canny(src,edge,10,200,3,true);
List<MatOfPoint> contours=new ArrayList<>();
//轮廓检测 CHAIN_APPROX_SIMPLE
Imgproc.findContours(edge,contours,hierarchy,Imgproc.RETR_CCOMP,Imgproc.CHAIN_APPROX_SIMPLE);
Mat mRgba=new Mat();
mRgba.create(edge.rows(), edge.cols(), CvType.CV_8UC3);
Bitmap b12= Bitmap.createBitmap(edge.cols(), edge.rows(),
Bitmap.Config.ARGB_8888);
if (contours.size()>0){
int i=0;
Log.i( "aaron","size "+contours.size() );
MatOfPoint temp_contour=contours.get(0);//假设最大的轮廓在index=0处
MatOfPoint2f approxCurve=new MatOfPoint2f();
// Imgproc.drawContours(test, contours, -1, new Scalar(0,255,0), 1);
//get points
List<MatOfPoint2f> newContours = new ArrayList<>();
for(MatOfPoint point : contours) {
MatOfPoint2f newPoint = new MatOfPoint2f(point.toArray());
Log.i( "aaron","MatOfPoint2f "+ newPoint.total() );
double[] temp;
Log.i( "aaron","Point----------------- ");
for (int j=0;j<newPoint.total();j++){
temp=newPoint.get( j,0 );
Point point1=new Point( temp[0],temp[1] );
Log.i( "aaron","Point "+ point1);
}
Log.i( "aaron","----------------- ");
newContours.add(newPoint);
}
Log.i( "aaron","轮廓数量: "+contours.size() );
Log.i( "aaron","hierarchy类型: "+hierarchy);
for(int k=0;k<hierarchy.cols();k++) {
double[] ds = hierarchy.get(0, k);
Log.i( "aaron","------------------ ");
Log.i( "aaron","轮廓下标: "+k );
for (int l=0;l<ds.length;l++) {
switch (l) {
case 0:
Log.i( "aaron","后一个轮廓下标: "+ds[l] );
break;
case 1:
Log.i( "aaron","前一个轮廓下标: "+ds[l] );
break;
case 2:
Log.i( "aaron","父轮廓下标: "+ds[l] );
break;
case 3:
Log.i( "aaron","内嵌轮廓下标: "+ds[l] );
break;
default:
break;
}
}
}
for (int idx=0;idx<contours.size();idx++) {
// Rect rect= Imgproc.boundingRect( contours.get( idx ) );
// Log.i( "aaron","rect "+rect.x+" "+rect.y+" "+rect.width+" "+rect.height );
// Imgproc.rectangle( test,new Point( rect.x,rect.y ),new Point( rect.x+rect.width,rect.y+rect.height ),new Scalar( 0,255,0 ) );
temp_contour = contours.get( idx );
Imgproc.drawContours(test, contours, idx, new Scalar(0,255,0), 2);
double contourarea = Imgproc.contourArea( temp_contour );
if (contourarea>0){
Log.i( "aaron","area "+contourarea );
// Imgproc.drawContours(test, contours, idx, new Scalar(0,255,0), 1);
//
i++;
}
}
Log.i( "aaron","area size "+i );
result.setText( "fail " );
Utils.matToBitmap(test,b12);
saveBitmap( b12 ,"1");
img3.setImageBitmap( b12 );
}else {
result.setText( "pass" );
}
}