`

OpenCVforAndroid应用之银行卡号识别 ------ 搞定开发环境

阅读更多

前阵子的考试、旅游让我有很长一阵子没来博客看看,现在寒假了,是时候写点、看点新的东西了!

前面我主要围绕着基于OpenCV的机器学习算法在图像识别处理上的应用来展开学习的,当然这些个技术(如银行卡号识别)最终都是要运用到实际生活中的。我们就拿银行卡号识别来说,大家用的最多的微信实际上就有了这个功能。大家打开微信钱包,绑定银行卡的时候是否在输入框右侧看到一个照相机一样的按钮呢,那就是实现银行卡号识别功能的地方。现在我们也模仿微信,将opencv机器学习移植到android上。

这个app是我之前用很短的时间完成的,旨在

1.进一步了解android编程

2.了解opencv移植到android的过程,方便开发

3.了解C++移植到android的过程,方便开发

我要完成的这个简单的app主要功能是:

1.通过手机相册中已有的照片(银行卡片)识别银行卡号(暂定农行)

2.通过手机拍照得到银行卡图片识别银行卡号(暂定农行)

 

由于开发时间较短,实现比较简单,主要是想尽快将成果整合出来,我将用两三篇博客总结一下主要技术要点,接下来是第一部分:

                                                             

                                            一、搞定开发环境

 

             (1) OpenCVforAndroid

               环境搭建

               1> eclipse for android(推荐直接下载adt-bundle-windows)

                    Java作为现在android编程最主流的语言,eclipse是必不可少的编程环境,现在网上有很多自带adt插件的eclipse,当然你也可以下载adt插件,在eclipse下配置,这里推荐前者,省心省事方便无穷。

                   2>导入OpenCV Library

                   在OpenCV官网下载最新的OpenCVforAndroid,解压到workspace所在盘下;
                                                     

                   进入eclipse,导入OpenCV Library(在项目一栏中右击选择Import);
                                                         选择上图所选选项

                  选择……\OpenCV-android-sdk\sdk,就可将OpenCV导入到Eclipse中。
                                                      

                                                      导入成功!


                     测试程序

                 1>新建一个android application project

                      2> 导入OpenCV Library,右键项目,点击“Bulid Path”,选择configure build path,add我们导入的OpenCV Library。

                      3> 编程验证:点击按钮,灰度化图片            

 

	<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: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.useopencvtest.MainActivity" >
	
	    <TextView
	        android:id="@+id/textView1"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="@string/hello_world" />
	
	    <ImageView
	        android:id="@+id/imageView2"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_alignLeft="@+id/imageView1"
	        android:layout_alignParentBottom="true"
	        android:layout_marginBottom="159dp"
	        android:src="@drawable/abc_ab_solid_light_holo" />
	
	    <ImageView
	        android:id="@+id/imageView1"
	        android:layout_width="100dp"
	        android:layout_height="150dp"
	        android:layout_below="@+id/textView1"
	        android:layout_centerHorizontal="true"
	        android:layout_marginTop="27dp"
	        android:src="@drawable/bank" />
	
	    <Button
	        android:id="@+id/button1"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_alignTop="@+id/imageView2"
	        android:layout_marginTop="43dp"
	        android:layout_toRightOf="@+id/imageView1"
	        android:text="Button" />
	
	</RelativeLayout>

 

 

 

 

package com.example.useopencvtest;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;

import android.content.pm.ApplicationInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

import com.example.useopencvtest.R.id;


public class MainActivity extends ActionBarActivity {
	ImageView image;
	Button btn;
	String TAG = "AAA";
	 //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);
        image = (ImageView)findViewById(R.id.imageView2);
        btn = (Button)findViewById(id.button1);
        btn.setOnClickListener( new  ProcessClickListener());  
    }
    
    private   class  ProcessClickListener  implements  OnClickListener{  
        
        @Override   
        public   void  onClick(View v) {  
            // TODO Auto-generated method stub   
        	use();
       	}  
   }  

    public void use()
    {
        Bitmap bitmap = getRes("bank");
        Mat temp = new Mat();
        Mat mat = new Mat();
    	Utils.bitmapToMat(bitmap, temp);
    	Imgproc.cvtColor(temp, mat, Imgproc.COLOR_BGR2GRAY);
    	Utils.matToBitmap(mat, bitmap);
    	this.image.setImageBitmap(bitmap); 
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    public Bitmap getRes(String name) {//获得res文件夹下的图片,得到bmp图片
   	 ApplicationInfo appInfo = getApplicationInfo();
   	 int resID = getResources().getIdentifier(name, "drawable", appInfo.packageName);
   	 return BitmapFactory.decodeResource(getResources(), resID);
   	 }
    
    @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);   
         
   }  
}

 结果:
                                                               
         参考:http://blog.csdn.net/yanzi1225627/article/details/16917961

              (2)Java的C++接口--------JNI

             环境搭建

             很多情况是开发者已经用C++进行了opencv的开发,想在移动端直接使用,这时候使用opencvforandroid就显得麻烦很多了,那这里我们可以使用Java中的JNI接口,直接调用C++的代码。

                 需要的工具:在(1)中的基础上,只需要安装NDK就可以了(r8版本以上)(注:现在你在百度上搜索的大部分还是写的NDK+Cygwin,但是实际上新版本的NDK(r8以上,我用的是r10版本)是不需要下载Cygwin,下过的朋友知道,这个玩意很坑的,我当初下了一个晚上都没下好)

                在下载安装好NDK后,参照             http://jingyan.baidu.com/article/5d6edee22d908799eadeec9f.html配置NDK。

 

               编程测试:

               MainActivity.java

              

package com.example.haveimgfun;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;


public class MainActivity extends ActionBarActivity {
	
	ImageView imgHuaishi;  
	Button btnNDK;
    
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imgHuaishi = (ImageView)findViewById(R.id.img_huaishi);
        btnNDK = (Button)findViewById(R.id.btn_gray_process);
      //  btnNDK.setOnClickListener( new  MyClickListener());  
        btnNDK.setOnClickListener(new OnClickListener()
        {//按钮事件
           public void onClick(View v) {
              // TODO Auto-generated method stub
        	   System.out.println("进来了");
        	   Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.img); 
        	   int h = src.getHeight();
        	   int w = src.getWidth();
        	   int temp[] = new int[h*w];
        	   int result[] = new int[h*w];
        	   src.getPixels(temp, 0, w, 0, 0, w, h);
        	   result = LibImgFun.ImgFun(temp, w, h);
        	   System.out.println("成功了");
        	   Bitmap last = Bitmap.createBitmap(w, h, Config.RGB_565);
        	   last.setPixels(result, 0, w, 0, 0, w, h);
        	   imgHuaishi.setImageBitmap(last); 
           }           
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

           LibImgFun.java

package com.example.haveimgfun;

public class LibImgFun {  
static {   
        System.loadLibrary("ImgFun");   
       }   
      /** 
            * @param width the current view width 
            * @param height the current view height 
*/ 
    public static native int[] ImgFun(int[] buf, int w, int h);  
}

 

右击项目,点击android tools选择add native support,这样会出现一个jni文件夹,我们新建文件如下:
                                                       
Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)  
OPENCV_CAMERA_MODULES:=off
override OPENCV_INSTALL_MODULES:=on
 OPENCV_LIB_TYPE:=SHARED

OPENCV_LIB_TYPE :=STATIC
$(info ==$(OPENCV_INSTALL_MODULES)==)
include G:/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk


LOCAL_MODULE    := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp

include $(BUILD_SHARED_LIBRARY)

  Application.mk

APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions 
APP_ABI:=armeabi armeabi-v7a 
APP_PLATFORM := android-8

 ImgFun.cpp

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C" {
JNIEXPORT jintArray JNICALL Java_com_example_haveimgfun_LibImgFun_ImgFun(
JNIEnv* env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT jintArray JNICALL Java_com_example_haveimgfun_LibImgFun_ImgFun(
JNIEnv* env, jobject obj, jintArray buf, int w, int h){
	jint *cbuf;
	cbuf = env->GetIntArrayElements(buf, NULL);
	if(cbuf == NULL)
	{
		return 0;
	}
	Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf);
	for(int j=0; j<myimg.rows/2; j++)
	{
		myimg.row(j).setTo(Scalar(0, 0, 0, 0));
	}
	int size=w*h;
	jintArray result = env->NewIntArray(size);
	env->SetIntArrayRegion(result, 0, size, cbuf);
	env->ReleaseIntArrayElements(buf, cbuf, 0);
	return result;
	}

}

 至此,环境搭建及测试完毕!

  • 大小: 91.3 KB
  • 大小: 27.4 KB
  • 大小: 37.6 KB
  • 大小: 6.7 KB
  • 大小: 176.4 KB
  • 大小: 2.9 KB
分享到:
评论
1 楼 cyw 2016-01-23  
写的很棒。加油

相关推荐

    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检测的代码,大家一起交流

    【车牌识别】 GUI BP神经网络车牌识别(带语音播报)【含Matlab源码 668期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【作业视频】六年级第1讲--计算专项训练(2022-10-28 22-51-53).mp4

    【作业视频】六年级第1讲--计算专项训练(2022-10-28 22-51-53).mp4

    3文件需求申请单.xls

    3文件需求申请单.xls

    【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】.zip

    【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】

    GOGO语言基础教程、实战案例和实战项目讲解

    GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解GO语言基础教程、实战案例和实战项目讲解

    全国计算机等级考试二级笔试样卷C语言程序设计

    全国计算机等级考试二级笔试样卷C语言程序设计主要考察考生对C语言编程的基础知识、语法和编程能力的掌握程度。考试内容主要包括C语言程序的结构、数据类型及其运算等基础知识,以及循环、条件语句、函数等编程能力。

    Excel模板个人简历文艺清新单页01.docx

    Excel模板个人简历文艺清新单页01.docx

    【图像边缘检测】自适应阈值的八方向和四方向sobel图像边缘检测【含Matlab源码 2058期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    HC070-3.5标定版描述文件及标定版ps文件

    HC070-3.5标定版描述文件及标定版ps文件

    【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】.zip

    【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】

    ISO文件电子文档发文删文记录表.xls

    ISO文件电子文档发文删文记录表.xls

    【红绿灯识别】机器视觉红绿灯识别【含Matlab源码 4044期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    【图像去噪】稀疏表示KSVD彩色图像去噪(含PSNR)【含Matlab源码 4261期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    node-v0.10.48-sunos-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.10.48-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    PREEvision关于ECU软件与诊断设计的一致性功能

    PREEvision关于ECU软件与诊断设计的一致性功能

    6c148dfb275925c73ba1861abbac5235.amr

    6c148dfb275925c73ba1861abbac5235.amr

Global site tag (gtag.js) - Google Analytics