前阵子的考试、旅游让我有很长一阵子没来博客看看,现在寒假了,是时候写点、看点新的东西了!
前面我主要围绕着基于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; } }
至此,环境搭建及测试完毕!
相关推荐
主要是在opencvforandroid的基础上实现了简单的车道线识别,同时增加了语音提示,还有简单的车型识别。效果还行,用多线程实现的。
自述文件 Aplicativocompatívelcom: Android SDK API-29 NDK 21.0.6113669 OpencvForAndroid 4.3.0 Dlib 19.19 执照
opencv基于android平台的人脸检测,分析OpencvforAndroid官网demo,用的是lbpcascade_frontalface模型文件,后面会添加mtcnn检测的代码,大家一起交流
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
3文件需求申请单.xls
【脑肿瘤检测】 GUI SOM脑肿瘤检测【含Matlab源码 2322期】
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语言程序的结构、数据类型及其运算等基础知识,以及循环、条件语句、函数等编程能力。
Excel模板个人简历文艺清新单页01.docx
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文件
【目标跟踪】 GUI帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】
ISO文件电子文档发文删文记录表.xls
Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
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.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软件与诊断设计的一致性功能
6c148dfb275925c73ba1861abbac5235.amr