`

OpenCVforAndroid应用之银行卡号识别 ------ 实战篇

阅读更多

上文中讲述了两种在android平台中使用opencv的办法,这里我将使用的是opencvforandroid的方法,也就是直接使用opencv提供的Java的API,这种方法对开发者来说是比较简单省事的。由于算法原理在《银行卡号识别》中已经阐述过,这里不再详细介绍,直接上关键代码!

 

 

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/backgroud"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.test.MainActivity" >
              <!-- 
         android:background="@drawable/bank" 
           --> 
           
                <ImageView
         android:id="@+id/img_huaishi"
         android:layout_width="250dp"
         android:layout_height="160dp"
         android:layout_alignParentTop="true"
         android:layout_marginTop="208dp" 
         android:layout_marginLeft="41dp" 
         />
             
     <Button   
         android:id = "@+id/btn_gray_process"   
         android:layout_width = "70dp"   
         android:layout_height = "70dp"   
         android:background="@drawable/xiangji"
         android:layout_below = "@id/img_huaishi"   
     	 android:layout_marginLeft="45dp"
     	 android:layout_marginTop="47dp"
           />
     
          <Button   
         android:id = "@+id/btn_pic"   
         android:layout_width = "70dp"   
         android:layout_height = "70dp"   
         android:background="@drawable/pic"
         android:layout_below = "@id/img_huaishi"   
     	 android:layout_marginLeft="197dp"
     	 android:layout_marginTop="47dp"
           /> 

   <!--   <ImageView
         android:id="@+id/title"
         android:layout_width="220dp"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="false"
         android:layout_alignParentTop="true"
         android:background="@drawable/title" /> -->


     <TextView
         android:id="@+id/mttext"
         android:layout_width="wrap_content"
         android:layout_height="40dp"
         android:layout_below="@+id/btn_pic"
         android:layout_marginTop="27dp"
         android:text="*******************"
         android:textColor="@android:color/black" 
         android:textSize="45px"
         android:layout_marginLeft="50dp"
          android:textStyle="bold"  
          />


</RelativeLayout>

 

效果预览图(图片效果请自行下载图片添加):
                                                    

MainActivity.java

package com.example.test;

import java.io.File;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.ml.CvKNearest;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


@SuppressLint("NewApi") public   class  MainActivity  extends  Activity {  
	
	//手机相册or手机相机相关参数
	private static int RESULT_LOAD_IMAGE = 1;
	
	int hehe = 0;
	
	int jisuan = 0;
	int error = 0;
	Button btnPic;  
    Button btnProcess;  
    Bitmap srcBitmap;  
    Bitmap grayBitmap;  
    Bitmap tempBitmap;  
    ImageView imgHuaishi;  
     private   static   boolean  flag =  false ;   
     private   static   boolean  isFirst =  true ;   
     private   static   final  String TAG =  "MyLogcat" ;  
     
     int numX1 = 0, numX2 = 0;
     int aa[], bb[];
     int bankX[];//19个银行卡号的位置信息----x
     int bankNum[];//19个银行卡号
     int classes = 10, train_samples = 1, K = 1;
     int new_width = 32;
     int new_height = 32;
     CvKNearest knn;
     Mat trainData, trainClasses;
     
     //OpenCV库加载并初始化成功后的回调函数   
     private  BaseLoaderCallback mLoaderCallback =  new  BaseLoaderCallback( this ) {  
  
         @Override   
         public   void  onManagerConnected( int  status) {  
             // TODO Auto-generated method stub   
             switch  (status){  
             case  BaseLoaderCallback.SUCCESS:  
                Log.i(TAG,  "成功加载" );  
                 break ;  
             default :  
                 super .onManagerConnected(status);  
                Log.i(TAG,  "加载失败" );  
                 break ;  
            }  
        }  
    };  
     @Override   
     protected   void  onCreate(Bundle savedInstanceState) {  
         super .onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        initUI();  
        //procSrc2Gray();
        pretreatment();//测试用
        btnProcess.setOnClickListener( new  ProcessClickListener());  
        btnPic.setOnClickListener( new  ProcessPicClickListener());  
    }  
  
  
     @Override   
     public   boolean  onCreateOptionsMenu(Menu menu) {  
           
        getMenuInflater().inflate(R.menu.main, menu);  
         return   true ;  
    }  
  
     public   void  initUI(){  
        btnProcess = (Button)findViewById(R.id.btn_gray_process);
        btnPic = (Button)findViewById(R.id.btn_pic); 
        imgHuaishi = (ImageView)findViewById(R.id.img_huaishi);  
        Log.i(TAG,  "initUI sucess..." ); 
        aa = new int[18];
        bb = new int[18];
        for(int i = 0; i < 18; ++i)
        {
        	aa[i] = 0;
        	bb[i] = 0;
        }
        bankX = new int[18];
        bankNum = new int[18];
		tempBitmap = getRes("shuai");
		this.imgHuaishi.setImageBitmap(tempBitmap); 
     }  
     
     public Bitmap getRes(String name) {//获得res文件夹下的图片,得到bmp图片
    	 ApplicationInfo appInfo = getApplicationInfo();
    	 int resID = getResources().getIdentifier(name, "drawable", appInfo.packageName);
    	 return BitmapFactory.decodeResource(getResources(), resID);
    	 }
     
     void getData()
     {//训练集的生成与保存
    	 Mat src_image = new Mat();
    	 Mat prs_image = new Mat(new Size(new_width, new_height),CvType.CV_8UC1);
    	 //Mat prs_image = new Mat();
    	 Mat row = new Mat(),data = new Mat(),rowb = new Mat(),datab = new Mat();
    	 int x,y;
  	   	 int c = 0;
  	     int cc = 0;
  	   	 int i,j,k = 0;
  		 int m = 0,n = 0;
    	 for (m = 0; m < classes; m++)
    	 {
    		 for (n = 0; n < train_samples; n++)
    		 {
    			 String name = "a" + String.valueOf(m) + String.valueOf(n);
    			 Bitmap bmp = getRes(name);
    			 if (bmp == null)
    			 {
    				 System.out.println("NULL Image");
    			 }
    			 Utils.bitmapToMat(bmp, src_image);
  		 		 /*src_image = Highgui.imread("/assets/a00.bmp");
  		 		 if (src_image == null)
    			 {
    				 System.out.println("NULL Image");
    			 }*/
  		 		 //System.out.println(String.valueOf(src_image.width()));
    			 //System.out.println(String.valueOf(src_image.channels()));
    			 Mat grayMat =  new  Mat();  //灰度图
    		     Mat binaryMat = new Mat(); //二值化图
    		     Mat mytemp = new Mat(new Size(new_width, new_height),CvType.CV_8U);
    		     Imgproc.cvtColor(src_image, grayMat, Imgproc.COLOR_RGBA2GRAY); //rgbMat to gray grayMat
   		         Imgproc.threshold(grayMat, binaryMat, 100, 255, Imgproc.THRESH_BINARY);//二值化
   		         //binaryMat = changeMat(binaryMat);
   		         binaryMat.copyTo(prs_image);
 		         Imgproc.resize(prs_image, mytemp, new Size(new_width, new_height));
   		         float imgData[] = new float[1];
   		         imgData[0] = (float)m;
   		         trainClasses.put(m * train_samples + n, 0, imgData);//trainClasses存入数据,注意trainClasses是32位浮点数
   		         Mat img = new Mat(new Size(mytemp.width(), mytemp.height()),CvType.CV_32FC1);
   		         mytemp.convertTo(img, CvType.CV_32FC1, 0.0039215);
   		         //prs_image.copyTo(img);
   		         img = img.reshape(0, 1);
 		         //Mat2IntArr(img);
   		         float tempData[] = new float[img.cols()];
   		         img.get(0, 0, tempData);
   		         //Mat2IntArr(binaryMat);
   		         trainData.put(m*train_samples + n, 0, tempData);
   		         //grayBitmap = Bitmap.createBitmap(prs_image.width(), prs_image.height(), Config.RGB_565);  
   	             //grayBitmap.setPixels(result, 0, w, 0, 0, w, h);
   		         //Utils.matToBitmap(prs_image, grayBitmap);  //convert mat to bitmap 
    		 }
    	 }
    	 //Mat2IntArr(trainData);
     }
     
     
     float do_ocr(Mat mat)
     {
    	 Mat pimage = new Mat();
    	 Mat data = new Mat();
    	 Imgproc.resize(mat, pimage, new Size(new_width, new_height));
    	 Mat image = new Mat(new Size(pimage.width(), pimage.height()),CvType.CV_32FC1);
    	 pimage.convertTo(image, CvType.CV_32FC1, 0.0039215);
    	 //Mat2IntArr(image);
    	 data = image.reshape(0, 1);
    	 Mat nearest = new Mat(new Size(K, 1), CvType.CV_32FC1);
    	 Mat results = new Mat();
    	 Mat dists = new Mat();
    	 //Mat2IntArr(data);
    	 float res = knn.find_nearest(data, K, results, nearest, dists);
    	 return res;
     }
     
     
     void sortBankNum()//对银行卡进行排序
     {
     	int i,j,temp; 
     	for(j=0;j<=17;j++) 
     	{
     		for (i=0;i<17-j;i++) 
     			if (bankX[i]>bankX[i+1]) 
     			{ 
     				temp=bankX[i]; 
     				bankX[i]=bankX[i+1]; 
     				bankX[i+1]=temp;
     				temp=bankNum[i]; 
     				bankNum[i]=bankNum[i+1]; 
     				bankNum[i+1]=temp;
     			}
     	} 
     	/*bankNum[0] = 6;
     	bankNum[1] = 2;
     	bankNum[2] = 2;
     	bankNum[3] = 8;
     	bankNum[4] = 4;
     	bankNum[5] = 8;*/
     }
     
     
     Mat  Filter(Mat imgSrc, Mat src, int t2)
     {//过滤图像
     	int a = 0, b = 0;//保存有效行号
     	int h = 0;
     	int state = 0;//标志位,0则表示还未到有效行,1则表示到了有效行,2表示搜寻完毕
     	for (int y = 0; y < imgSrc.height(); y++)
     	{
     		int count = 0;
     		for (int x = 0; x < imgSrc.width(); x++)
     		{
     			//System.out.println("ok");
     			byte[] data = new byte[1];
     			imgSrc.get(y, x, data);
     			//System.out.println("ok2");
     			if (data[0] == 0)
     				count = count + 1;
     		}
     		if (state == 0)//还未到有效行
     		{
     			if (count >= 10)//找到了有效行
     				{//有效行允许十个像素点的噪声
     					a = y;
     					state = 1;
     				}
     		}
     		else if (state == 1)
     		{
     			if (count <= 10)//找到了有效行
     				{//有效行允许十个像素点的噪声
     					b = y;
     					state = 2;
     				}
     		}
     	}
     	numX1 = a;
     	numX2 = b;
     	System.out.println(Integer.toString(a));
     	System.out.println(Integer.toString(b));
     	
     	if (b - a > 10)
     	{   	
     			Rect roi = new Rect(0, a, src.width(), b - a);   
     			//Mat res = cvCreateImage(cvSize(roi.width, roi.height), 8, 1);  
     			Mat res = new Mat(new Size(roi.width, roi.height),CvType.CV_8UC1);
     			//IplImage *orig = cvCreateImage(cvSize(roi.width, roi.height), 8, 1);
     			Mat orig = new Mat(new Size(roi.width, roi.height),CvType.CV_8UC1);
     			//cvSetImageROI(src, roi);   
     			byte[] data = new byte[roi.width * roi.height];
     			src.get(a, 0, data);
     			orig.put(0, 0, data);
     			Imgproc.threshold(orig, res, t2, 255, Imgproc.THRESH_BINARY);//二值化 55
     	        /*Size size = new Size(3, 3);
     	        Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, size);
     	        Imgproc.erode(res, res, element);//腐蚀图像	
     			*/
     			int newW = (int)(res.width()/3);
     			int newW2 = (int)(2 * res.width()/3);
     			Mat temp = new Mat(new Size(newW2, res.height()),CvType.CV_8UC1);
     			byte[] Tempdata = new byte[newW2];
     			for (int i = 0; i < res.height(); ++i)
     			{
     				res.get(i, newW, Tempdata);
     				temp.put(i, 0, Tempdata);
     			}
     			System.out.println("矩阵赋值成功了!");
     			System.out.println(String.valueOf(temp.cols())+"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +String.valueOf(temp.rows()));
     			tempBitmap = Bitmap.createBitmap(temp.cols(), temp.rows(), Config.RGB_565);
     			Utils.matToBitmap(temp, tempBitmap);
     			//this.imgHuaishi.setImageBitmap(tempBitmap);  
     		//return res;
     			return temp;
     	}
     	else
     		return null;
     }
  
     
    void coutIntArr(int[] temp, int[] temp2)
    {
    	for (int i = 0; i < temp.length; ++i)
    	{
    		  System.out.println(String.valueOf(temp[i])+ "+" + String.valueOf(temp2[i]));
    	}
    }
    
    public Mat cutMat(Mat imgSrc)
    {
     	int a = 0, b = 0;//保存有效行号
     	int h = 0;
     	int state = 0;//标志位,0则表示还未到有效行,1则表示到了有效行,2表示搜寻完毕
     	for (int y = 0; y < imgSrc.height(); y++)
     	{
     		int count = 0;
     		for (int x = 0; x < imgSrc.width(); x++)
     		{
     			//System.out.println("ok");
     			byte[] data = new byte[1];
     			imgSrc.get(y, x, data);
     			//System.out.println("ok2");
     			if (data[0] == 0)
     				count = count + 1;
     		}
     		if (state == 0)//还未到有效行
     		{
     			if (count >= 10)//找到了有效行
     				{//有效行允许十个像素点的噪声
     					a = y;
     					state = 1;
     				}
     		}
     		else if (state == 1)
     		{
     			if (count <= 3)//找到了有效行
     				{//有效行允许十个像素点的噪声
     					b = y;
     					state = 2;
     					break;
     				}
     		}
     	}
     	Log.i("MyLogcat",  "开始截取图片"+String.valueOf(imgSrc.width())+"+"+ String.valueOf(b - a));  
     	Rect roi = new Rect(0, a, imgSrc.width(), b - a); 
     	Mat res = new Mat(new Size(roi.width, roi.height),CvType.CV_8UC1);
     	res = imgSrc.submat(roi);
     	Log.i("MyLogcat",  "截取成功");  
     	if (hehe == 5)
     	{
			//tempBitmap = Bitmap.createBitmap(res.cols(), res.rows(), Config.RGB_565);
 			//Utils.matToBitmap(res, tempBitmap);
 			//this.imgHuaishi.setImageBitmap(tempBitmap);  
     	}
    	return res;
    }
     
   
     
     public   int  procSrc2Gray(int t, int t2){  
        Mat rgbMat =  new  Mat(); //原图 
        Mat grayMat =  new  Mat();  //灰度图
        Mat binaryMat = new Mat(); //二值化图
        Mat erode = new Mat();
        Mat last = new Mat();

        //srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a2);  
        //srcBitmap = getRes("a00");
        
        //grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Config.RGB_565);  
        Utils.bitmapToMat(srcBitmap, rgbMat); //convert original bitmap to Mat, R G B. 
        Bitmap bitP = srcBitmap;
        Imgproc.resize(rgbMat, rgbMat, new Size(589, 374));
        Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY); //rgbMat to gray grayMat
        //Mat2IntArr(grayMat);
        //继续预处理
        Imgproc.threshold(grayMat, binaryMat, t, 255, Imgproc.THRESH_BINARY);//二值化

         //Mat2IntArr(binaryMat);
        Imgproc.medianBlur(binaryMat, binaryMat, 3);
        Size size = new Size(3, 3);
        Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, size);
        Imgproc.erode(binaryMat, erode, element);//腐蚀图像      
        //System.out.println(Integer.toString(erode.channels()));
        Log.i("MyLogcat",  "进入Filter" );  
        last = Filter(erode,grayMat, t2);
        Log.i("MyLogcat",  "完成Filter" );  
 	
	       //Mat2IntArr(res); 
        boolean a1;
        if (last != null)
        {
	        Log.i("MyLogcat",  "进入findRect" );  
	        a1 = findRect(last);
        }
        else
        {
        	a1 = false;
        }
        if(a1)
        {
            Log.i("MyLogcat",  "完成findRect1111" ); 
	        //System.out.println(String.valueOf(aa.length)+" "+String.valueOf(bb.length));
	        /*for (int a = 0; a < 19; a++)
	        {
	        	System.out.println(String.valueOf(aa[a])+" "+String.valueOf(bb[a]));
	        }*/
	        
	        //Imgproc.medianBlur(last, last, 3);
	       
	        //************将mat转换成int[],送给c++进行处理*************
	        /*int h = last.height();
	        int w = last.width();
	        int temp[] = new int[h*w];
	        int result[] = new int[h*w];
	        temp = Mat2IntArr(last);
	        result = LibImgFun.ImgFun(temp, w, h);
	        System.out.println(String.valueOf(result[0]));
			*/
	        /*String path = "bank";
	        Bitmap bmp = getRes(path);
	        if (bmp == null)
	        {
	        	System.out.println("NULL Image");
	        }
	        System.out.println(String.valueOf(bmp.getHeight()) + " " + String.valueOf(srcBitmap.getHeight()));
	        imgHuaishi.setImageBitmap(bmp);*/
	       
	        trainData = new Mat(new Size(new_width * new_height, classes * train_samples),CvType.CV_32FC1);
	        trainClasses = new Mat(new Size(1, classes * train_samples),CvType.CV_32FC1);
	       
	       getData();//得到训练数据
	       knn = new CvKNearest();
	       Mat sampleIdx = new Mat();
	       //boolean a = knn.train(trainData, trainClasses, sampleIdx, false, K, false);
	       boolean a = knn.train(trainData, trainClasses);
	       
	       //float ret = do_ocr(binaryMat);
	       //System.out.println(String.valueOf(ret));
	       
	       //分割得到数字
	       Mat orig = new Mat();
	       last.copyTo(orig);
	       Mat bininv_img = new Mat();
	       int c = 0;
	       hehe = 0;
	       error = 0;
	       for (int i = 0; i < 18; i++)
	       {	
	    	   c++;
	    	   hehe++;
	    		if (bb[i] - aa[i] < 5)
	     		{
	    			Log.i("MyLogcat",  "忽略" ); 
	    			bankX[i] = 0;
	    			bankNum[i] = 0;
	    			error++;
	     			continue;
	     		}
	    	   Rect roi = new Rect(aa[i], 0, bb[i] - aa[i], numX2 - numX1);
	    	   bankX[i] = aa[i];//保存位置信息
	    	   Mat res = new Mat();
	    	   res = orig.submat(roi);
	    	   if(c == 7)
	    	   {
	    		   //grayBitmap = Bitmap.createBitmap(res.width(), res.height(), Config.RGB_565);  
	    	       //Utils.matToBitmap(res, grayBitmap);  //convert mat to bitmap 
	    	       //Mat2IntArr(res); 
	    	   }
	    	   
	    	   float ret = do_ocr(res); 
	    	   bankNum[i] = (int)ret;
	       }
	        Log.i("MyLogcat",  "本次识别失败数是:"+String.valueOf(error));  
	        Log.i("MyLogcat",  "进入sortBankNum" );  
	   		coutIntArr(bankNum, bankX);
	   		
	   		sortBankNum();
	   		coutIntArr(bankNum, bankX);
	   		Log.i("MyLogcat",  "完成sortBankNum" );  
	
	   		String x = new String();
	   		x = "622848";
	   		int finish = 0;
	   		for (int i = 0; i < 18; ++i)
	   		{
	   			if(i + error > 17)
	   			{
	   				break;
	   			}
	   			if(bankX[i + error] != 0)
	   			{
	   				x = x + String.valueOf(bankNum[i + error]);
	   				Log.i("MyLogcat",  String.valueOf(bankNum[i + error]) + "+" +  String.valueOf(i + error) );  
	   				finish++;
	   				if(finish >= 13)
	   				{
	   					break;
	   				}
	   			}
	   		}
	   	
	   	        this.imgHuaishi.setImageBitmap(bitP);
		   		Log.i("MyLogcat",  "准备放置结果了!" );  
		   		Toast.makeText(MainActivity.this, "卡号已经复制到剪切板!!!", 3).show();  
		   		TextView text = (TextView)findViewById(R.id.mttext);
		   		//x = "6228481099312404479";
		   		text.setText(x);
		   		ClipboardManager myClipboard;
		   		myClipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
		   		ClipData myClip;
		   		myClip = ClipData.newPlainText("text", x);
		   		myClipboard.setPrimaryClip(myClip);
	   		
	      /* grayBitmap = Bitmap.createBitmap(last.width(), last.height(), Config.RGB_565);  
	       //grayBitmap.setPixels(result, 0, w, 0, 0, w, h);
	       Utils.matToBitmap(last, grayBitmap);  //convert mat to bitmap*/ 
	       Log.i("MyLogcat",  "procSrc2Gray sucess..." );  
	       return error;
        }
        else
        {
    		TextView text = (TextView)findViewById(R.id.mttext);
	   		text.setText("*******************");
        tempBitmap = getRes("shuai");
    	this.imgHuaishi.setImageBitmap(tempBitmap); 
         Log.i("MyLogcat",  "完成findRect2222" ); 
         System.out.println("?????????????????????????????????");
   		 Toast.makeText(MainActivity.this, "本次识别失败,请在光线较亮的地方再次尝试!!", 3).show();  
   		 srcBitmap.recycle();   //回收图片所占的内存
   		 return 1;
        }
     }  
     
     
     boolean findRect(Mat srcA)
     {//将银行数字分割,黑点为前景点,白点为背景点。
     	int count = 0;
     	int judgeA = 0;//0代表当前要判断有效列,1代表当前要判断无效列
     	int i = 0;
     	Mat src = new Mat();
     	if (srcA == null)
     	{
     		return false;
     	}
     	Imgproc.medianBlur(srcA, src, 3);
     	//srcA.copyTo(src);
     	//cvSmooth(srcA, src, CV_MEDIAN);
     	for (int x = 0; x < src.width(); x++)
     	{
     		count  = 0;
     		for (int y = 0; y < src.height(); y++)
     		{
     			byte[] data = new byte[1];
     			src.get(y, x, data);
     			if (data[0] == 0)//遇到前景点就加1
     			{
     				count ++;
     			}
     		}
     		if (judgeA == 0)
     		{
     			if (count >= 5)//有效行到了
     			{
     				judgeA = 1;
     				if (i > 17)
     				{
     					i = 17;
     				}
     				aa[i] = x;
     			}
     		}
     		else if(judgeA == 1)
     		{
     			if (count < 5)
     			{
     				judgeA = 0;
     				if (i > 17)
     				{
     					i = 17;
     				}
     				bb[i] = x;
     				i++;
     			}
     		}
     	}
     	//coutIntArr(bb, aa);
     	/*
     	for (int ii = 0; ii < 19; ++ii)
     	{
     		if (bb[ii] - aa[ii] < 5)
     		{
     			return false;
     		}
     	}*/
     	return true;
     	
     	/*for (int m = 0; m < i; m++)
     	{
     	
     		cvLine(src, cvPoint(aa[m], 0), cvPoint(aa[m], src->height), cvScalar(0, 0, 0));
     		cvLine(src, cvPoint(bb[m], 0), cvPoint(bb[m], src->height), cvScalar(0, 0, 0));
     	}*/
     	
         /*cvNamedWindow("img");
     	cvShowImage("img", src);
     	cvWaitKey(0);
     		*/	 
     }
     
     
     public float[] Mat2IntArr(Mat mat)
     {
		 int h = mat.height();
		 int w = mat.width();
		 float result[] = new float[h*w];
		 for (int i = 0; i < h; ++i)
		 {
			 for (int j = 0; j < w; ++j)
			 {
				 float[] data = new float[1];
	     			mat.get(i, j, data);
	     			if( data[0] == 0)
	     				result[w * i + j] = 0;
	     			else
	     				result[w * i + j] = 255;
	     		    System.out.println("("+String.valueOf(i)+","+String.valueOf(j)+")"+String.valueOf((float)data[0]));
			 }
		 }
		 System.out.println(String.valueOf(h)+","+String.valueOf(w));
    	 return result;
     }
     
     public Mat changeMat(Mat mat)
     {
    	 int h = mat.height();
		 int w = mat.width();
		 //int result[] = new int[h*w];
		 for (int i = 0; i < h; ++i)
		 {
			 for (int j = 0; j < w; ++j)
			 {
					byte[] data = new byte[1];
	     			mat.get(i, j, data);
	     			if( data[0] != 0)
	     			{
	     				data[0] = (byte)255;
	     				mat.put(i, j, data);
	     			}
			 }
		 }
		 return mat;
     }
     
     
     
     public void pretreatment()
     {//读入原始图片
    	 	/*Mat src = Highgui.imread("bank.jpg");
    	 	if (src == null)
    	 	{
    	 		 Log.i(TAG,  "LOAD FAILED ..." ); 
    	 		 return;
    	 	}*/
    	 Bitmap bm1=BitmapFactory.decodeFile("/drawable-hdpi/bank.jpg");  
    	 if (bm1 == null)
 	 	{
    		 //Toast.makeText(MainActivity.this, "===========图片读取失败!============!!", 3).show();  
 	 		 return;
 	 	}
    	 imgHuaishi.setImageBitmap(bm1); 
    	 	
     }
  
     
     
     
     private   class  ProcessClickListener  implements  OnClickListener{  
          
         @Override   
         public   void  onClick(View v) {  
             // TODO Auto-generated method stub   
            /* if (isFirst)  
            {  
                procSrc2Gray();  
                isFirst =  false ;  
            }  
             if (flag){  
                imgHuaishi.setImageBitmap(grayBitmap);  
                btnProcess.setText( "查看原图" );  
                flag =  false ;  
            }  
             else {  
                imgHuaishi.setImageBitmap(srcBitmap);  
                btnProcess.setText( "灰度化" );  
                flag =  true ;  
            }  */
        	/* Intent i = new Intent(
                     Intent.ACTION_PICK,
                     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
             startActivityForResult(i, RESULT_LOAD_IMAGE);*/
        	 camera();
        }  
    }  
     
     private   class  ProcessPicClickListener  implements  OnClickListener{  
         
         @Override   
         public   void  onClick(View v) {  
             // TODO Auto-generated method stub   
          
        	 Intent intent = new Intent(
                     Intent.ACTION_PICK,
                     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
             startActivityForResult(intent, RESULT_LOAD_IMAGE);
        }  
    }  
     
    /* @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
    	 System.out.println("图片选择成功");
         if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
             Uri selectedImage = data.getData();
             String[] filePathColumn = { MediaStore.Images.Media.DATA };
   
             Cursor cursor = getContentResolver().query(selectedImage,
                     filePathColumn, null, null, null);
             cursor.moveToFirst();
   
             int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
             String picturePath = cursor.getString(columnIndex);
             cursor.close();
             System.out.println("是不是这里的问题?");
             imgHuaishi.setImageBitmap(BitmapFactory.decodeFile(picturePath));
             srcBitmap = BitmapFactory.decodeFile(picturePath);
        	 System.out.println("进入主函数");
        	 System.out.println(String.valueOf(srcBitmap.getWidth()) + " and " + String.valueOf(srcBitmap.getHeight()));
             procSrc2Gray();
             new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					MainActivity.this.runOnUiThread(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							//procSrc2Gray();
							 System.out.println("线程进来了");
						}
					});
				}
			}).start();
         }
   
     }*/
     
     
     /*
      * 从相机获取
      */
     
     private static final int PHOTO_REQUEST_CAREMA = 1;
     private static final int PHOTO_REQUEST_GALLERY = 2;
     private static final int PHOTO_REQUEST_CUT = 3;
     private static final String PHOTO_FILE_NAME = "temp_photo.jpg";
     private File tempFile;
     /**
     * 判断手机是否有SD卡。
     * 
     * @return 有SD卡返回true,没有返回false。
     */
     public static boolean hasSDCard() {
     return Environment.MEDIA_MOUNTED.equals(Environment
     .getExternalStorageState());
     }
     public void camera() {
         // 激活相机
         Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
         // 判断存储卡是否可以用,可用进行存储
         if (hasSDCard()) {
             tempFile = new File(Environment.getExternalStorageDirectory(),
                     PHOTO_FILE_NAME);
             // 从文件中创建uri
             Uri uri = Uri.fromFile(tempFile);
             intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
         }
         // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
         startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
     }
     
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	 if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
             Uri selectedImage = data.getData();
             String[] filePathColumn = { MediaStore.Images.Media.DATA };
   
             Cursor cursor = getContentResolver().query(selectedImage,
                     filePathColumn, null, null, null);
             cursor.moveToFirst();
   
             int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
             String picturePath = cursor.getString(columnIndex);
             cursor.close();
             System.out.println("是不是这里的问题?");
             imgHuaishi.setImageBitmap(BitmapFactory.decodeFile(picturePath));
             srcBitmap = BitmapFactory.decodeFile(picturePath);
        	 System.out.println("进入主函数");
        	 System.out.println(String.valueOf(srcBitmap.getWidth()) + " and " + String.valueOf(srcBitmap.getHeight()));
             procSrc2Gray(28, 30);
    	 }
    	 
    	 
    	 
    	 
    	 else if (requestCode == PHOTO_REQUEST_GALLERY) {
             // 从相册返回的数据
             if (data != null) {
                 // 得到图片的全路径
                 Uri uri = data.getData();
                 crop(uri);
             }
  
         } else if (requestCode == PHOTO_REQUEST_CAREMA) {
             // 从相机返回的数据
             if (hasSDCard()) {
                 crop(Uri.fromFile(tempFile));
             } else {
                 Toast.makeText(MainActivity.this, "未找到存储卡,无法存储照片!", 0).show();
             }
  
         } else if (requestCode == PHOTO_REQUEST_CUT) {
             // 从剪切图片返回的数据
             if (data != null) {
                 Bitmap bitmap = data.getParcelableExtra("data");
                 //this.imgHuaishi.setImageBitmap(bitmap);
                 srcBitmap = bitmap;
                 Log.i("MyLogcat",  "procSrc2Gray 进来了!" );  
                 //int i = 40;
                 //int judge = 1;
                 //while(judge > 0)
                 //{//错误大于0则继续
                	  procSrc2Gray(45, 55);//43
                	 //i++;
                	 //if (i >= 45)
                	 //{
                		 //System.out.println("?????????????????????????????????");
                   		 //Toast.makeText(MainActivity.this, "本次识别失败,请在光线较亮的地方再次尝试!!", 3).show();  
                		 //break;
                	 //}
                 //}
             }
             try {
                 // 将临时文件删除
                 tempFile.delete();
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
  
         super.onActivityResult(requestCode, resultCode, data);
     }
     
     /*
      * 剪切图片
      */
     private void crop(Uri uri) {
         // 裁剪图片意图
         Intent intent = new Intent("com.android.camera.action.CROP");
         intent.setDataAndType(uri, "image/*");
         intent.putExtra("crop", "true");
         // 裁剪框的比例,1:1
         intent.putExtra("aspectX", 8);
         intent.putExtra("aspectY", 1);
         // 裁剪后输出图片的尺寸大小
         intent.putExtra("outputX", 800);
         intent.putExtra("outputY", 100);
  
         intent.putExtra("outputFormat", "JPEG");// 图片格式
         intent.putExtra("noFaceDetection", true);// 取消人脸识别
         intent.putExtra("return-data", true);
         // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
         startActivityForResult(intent, PHOTO_REQUEST_CUT);
     }

  
  
     @Override   
     protected   void  onResume() {  
         // TODO Auto-generated method stub   
         super .onResume();  
         //load OpenCV engine and init OpenCV library   
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, getApplicationContext(), mLoaderCallback);  
        Log.i(TAG,  "onResume sucess load OpenCV..." );  
//      new Handler().postDelayed(new Runnable(){   
//   
//          @Override   
//          public void run() {   
//              // TODO Auto-generated method stub   
//              procSrc2Gray();   
//          }   
//             
//      }, 1000);   
          
    }  
      
      
      
  
}  

 简易APP编写完毕

  • 大小: 61.4 KB
分享到:
评论
2 楼 zzzimooo 2016-09-09  
请问博主,大概在130行:
Bitmap bmp = getRes(name);
这些资源文件能提供一下吗?谢谢
1 楼 u010074054 2016-03-21  
您好,我想请教一下关于银行卡识别的问题,您方便加一下我QQ吗?我的QQ是1115995035,谢谢

相关推荐

    lane-detection.rar_Java车道_java 车道识别_lane-detection_多车道_车道线

    主要是在opencvforandroid的基础上实现了简单的车道线识别,同时增加了语音提示,还有简单的车型识别。效果还行,用多线程实现的。

    TRsign:使用HOG + SVM(dlib 19.19 + opencv 4.3.0)检测TRsign

    自述文件 Aplicativocompatívelcom: Android SDK API-29 NDK 21.0.6113669 OpencvForAndroid 4.3.0 Dlib 19.19 执照

    Android+Opencv(人脸检测 lbpcascade_frontalface)

    opencv基于android平台的人脸检测,分析OpencvforAndroid官网demo,用的是lbpcascade_frontalface模型文件,后面会添加mtcnn检测的代码,大家一起交流

    #这是一篇关于 LabVIEW 介绍说明、使用技巧和优缺点对文章

    labview

    重庆大学数字电子技术试题.pdf

    重庆大学期末考试试卷,重大期末考试试题,试题及答案

    重庆大学2012电磁场考题(A)参考答案及评分标准.pdf

    重庆大学期末考试试卷,重大期末考试试题,试题及答案

    5G智慧港口解决方案.pptx

    在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

    机械工程学位 Matlab.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    Matlab菌丝检测识别项目.zip

    提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

    基于django-xadmin的idc资产管理应用.zip

    基于django-xadmin的idc资产管理应用.zip

    电商数据分析.py

    电商数据分析.py

    头哥机组练习-第4关:16位快速加法器设计(计算机组成原理-谭志虎-华科大)

    头哥机组练习-第4关:16位快速加法器设计(计算机组成原理-谭志虎-华科大)

    Python实现春节烟花模拟介绍及代码示例.docx

    春节,作为中国最重要的传统节日之一,象征着团圆、喜庆和新的开始。烟花作为春节庆祝活动的重要元素,以其绚烂多彩、瞬间绽放的特点,给人们带来了无尽的欢乐和惊喜。然而,由于环境保护和安全的考虑,现实中烟花的燃放受到了诸多限制。因此,利用编程技术,模拟出春节烟花的效果,成为了一种新颖而有趣的方式。 本文将介绍一种基于Python编程语言的春节烟花模拟代码。通过简单的代码实现,我们可以创建出各种形态、颜色和动态效果的烟花,让人们在计算机屏幕上欣赏到一场别样的“烟花盛宴”。 一、代码介绍 该代码主要使用了Python的图形库pygame,以及random库来生成随机颜色和位置。pygame库是一个用于编写视频游戏的Python模块集,它可以创建窗口、绘制图形、处理键盘和鼠标事件等。random库则用于生成随机数,以模拟烟花的随机性和不确定性。 在代码中,我们定义了一个烟花类(Firework),包含烟花的初始位置、颜色、速度等属性,以及一个方法(update)用于更新烟花的位置和状态。然后,在主程序中,我们创建了一定数量的烟花对象,并在每一帧中更新它们的状态,同时在屏幕上绘制出来。 通过调整烟花类

    财务数据分析看版.xlsx

    Excel数据看板,Excel办公模板,Excel模板下载,Excel数据统计,数据展示

    social ski driver algorithm社会滑雪优化算法附matlab代码.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    辐射状系统配电网中的潮流解matlab代码.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    LabVIEW的概要分析与介绍

    LabVIEW(Laboratory Virtual Instrument Engineering Workbench)是一款由美国国家仪器公司(National Instruments)开发的图形化编程语言和开发环境,广泛应用于数据采集、控制系统、测试测量、科学研究等领域。以下是关于 LabVIEW 的资源描述: 开发环境和工具:LabVIEW 提供了一个直观易用的开发环境,允许用户通过拖放式的方式创建虚拟仪器(Virtual Instruments,简称VIs)并连接它们,构建复杂的控制和测量系统。LabVIEW 还提供了丰富的图形化编程工具和函数库,包括数据处理、信号分析、仪器控制等功能,极大地简化了开发过程。 图形化编程语言:LabVIEW 使用图形化编程语言 G(Graphical Programming Language)进行编程,采用了数据流编程模型,使得程序的逻辑结构更直观清晰。用户可以通过连接各种图形化的函数块(Node)来实现数据处理、控制逻辑等功能,无需编写复杂的代码,降低了学习和开发的门槛。 应用领域:LabVIEW 在科学研究、工程控制、教育培训等领域有着

    单片机实验或课设-定时器控制交通指示灯

    定时器控制交通指示灯 用C语言编写,也可以改成汇编

    城区智慧城市感知建设项目-设计方案(306页WORD).docx

    共建共享共治智慧城市感知系统,实现视频资源的集约化;视频感知,AI加持,构建视频AI资源池;融合感知数据与业务数据;实现城市状态的实时监测、城市异常的智能预警以及对事件的主动学习、预警和决策模型的自动训练,以数据和知识驱动实现城市日常治理、公共服务、应急处置和发展筹划等业务的可视化、智能化、可量化评估与持续优化,推动城市治理体系和治理能力现代化;从而有效支撑综合类业务及探索运营类业务。 在现有建设的基础上,补全前端多维信息感知设备包括路口交通感知、规范交通标示、人脸抓拍、信号控制等系统,为政府综合业务、承载城市运行管理、应急指挥、民生服务等业务,重点在运行监测、协同指挥、仿真决策、开放服务等方面,通过全面感知城市运行状态,实现城市日常运行管理以及突发事件应急联动指挥等全景指挥中心功能。

    阿里巴巴笔试题目.docx

    校园招聘笔试题目及答案

Global site tag (gtag.js) - Google Analytics