需求分析

第一步我对该实验做了一个完整性的需求分析:

我们需要做到以下几点:

(1)学生信息的管理,对学生的信息的添加,删除,编译修改;

(2)基于每个学生的人脸上传,并识别该图片是否是一个人脸图片;

(3)基于上传后的学生人脸,进行同一个人的不同角度,不同角度进行不同程度的人脸识别控制;

(4)开启二维码扫描功能,解析二维码的含义;

(5)开启物品识别功能;

4.2 数据考察和数据收集

android 28天签到功能实现 安卓签到系统_人脸识别

系统分为以下三部分:

android 28天签到功能实现 安卓签到系统_Android开发_02

4.4 系统实际操作流程

android 28天签到功能实现 安卓签到系统_人脸识别_03

4.5 实际操作实现
4.5.1 主页面的设计:

布局采取LinearLayout线性布局,因为手机屏幕的大小有限,所以采取使用ScrollView控件,使得该activity布局页面可以添加入更多的控件,在ScrollView中添加控件到屏幕以外后,它会自动的向下滑动并把该控件包含在屏幕中,不会使控件无法显示在屏幕中。在ScrollView中继续使用线性布局,在线性布局的第一行中嵌套一个LinearLayout线性布局,使用一个relativeLayout布局添加app的header,在线性布局的第二,第三,第四,第五行对应的是学生信息管理、查询学生信息、学生人脸上传、点名系统模块。

额外添加: 因为系统自带顶部tittle不美观,所以设计了一个tittle.xml插入到每一个页面,在后面的报告中不再馁述。

添加代码:

android 28天签到功能实现 安卓签到系统_android 28天签到功能实现_04


TitleLayout代码如下:

显示:

android 28天签到功能实现 安卓签到系统_Android开发_05


Xml代码

android 28天签到功能实现 安卓签到系统_人脸识别_06


主页面如下:

android 28天签到功能实现 安卓签到系统_android 28天签到功能实现_07


因为该主题是图像处理,所以该报告主要解释上传头像和点名系统的人脸图像处理模块

4.5.2 学生信息模块:

(1)布局解释

主布局设计为线性布局,设计list列表的每一列的列名,采用listview显示学生的基本信息,因为手机的屏幕宽度有限,所以我设计在listview 中只显示学生图片,学生的id号,学生的姓名,学生的联系方式(电话号码),在每一行的节点item的尾部设计删除按键,可以选择删除指定学生,并实现listview节点item点击事件,点击节点item显示该学生的详细信息,在显示详细信息后可选择编译按钮对学生信息的修改,注意:学生的id号无法修改,因为用id特征分辨不同学生,不能存在两个相同id的学生。在信息添加的过程中使用了以下几种控件,以简便输入学生的信息:在性别选择上使用单选框控件RadioButton,分别只能选择男或者女;在年龄上使用下拉式菜单,选择1岁50岁;在班级上使用下拉式菜单,只能选择13班中的一个选项。点击按钮添加后,会验证每一个选项是否填入正确,若非法则提示相应提醒。

(2)布局显示

android 28天签到功能实现 安卓签到系统_Android开发_08

android 28天签到功能实现 安卓签到系统_人脸识别_09


添加信息后会使所有填入信息置为空,并相应提醒填入的值。

(3)逻辑代码实现

①Listview显示逻辑代码:

获取lv实例:

lv = (ListView) findViewById(R.id.lv);

执行lv.setAdapter(new Adapter); listview适配器代码显示listview中的item值
②自定义适配器代码:

private class MyAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return dao.getTotalCount();
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = View.inflate(addstudent.this,R.layout.item,null);
            TextView tv_item_id = (TextView) view.findViewById(R.id.tv_item_id);
            TextView tv_item_name = (TextView) view.findViewById(R.id.tv_item_name);
            TextView tv_item_phone = (TextView) view.findViewById(R.id.tv_item_phone);
            ImageView touxiang_image=(ImageView) view.findViewById(R.id.student_image);
            ImageView iv_delete = (ImageView) view.findViewById(R.id.iv_delete);
            final Map<String, String> map = dao.getStudentInfo(position);
            iv_delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    boolean result = dao.delete(map.get("studentid"));
                    if (result) {
                        Toast.makeText(addstudent.this,"删除成功", Toast.LENGTH_SHORT).show();
                        lv.setAdapter(new MyAdapter());
                    }
                }
            });
            //界面只显示三列即可
            tv_item_id.setText(String.valueOf(map.get("studentid")));
            tv_item_name.setText(map.get("name"));
            tv_item_phone.setText(map.get("phone"));

            //此处image 初始使用同一个默认图片
            if(map.get("touxiang_id")==null||map.get("touxiang_id").equals("1")){
                touxiang_image.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.jjy1));
            }
            else {
                touxiang_image.setImageBitmap(getimage(map.get("touxiang_id")));
            }
            return view;
        }

        @Override
        public StudentInfo getItem(int position) {
//            return list.get(position);
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }
    }

把自定义适配器传入lv适配器拷贝构造函数中,使lv初始化本地SQLit数据库中的学生信息数据。
③点击事件的实现:用AlertDialog+View 定义显示框,显示出学生的详细信息,并且添加确定和编译按钮,实现编译和确定的事件:
显示框的初始化:

final LayoutInflater inflater=addstudent.this.getLayoutInflater();
final View view1=inflater.inflate(R.layout.authorize_dialog,null,false);

Context mContext=addstudent.this;

AlertDialog.Builder builder=new AlertDialog.Builder(mContext);
builder.setView(view1);
builder.setCancelable(false);
final AlertDialog alert=builder.create();
Listview的item点击事件:
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        final Map<String, String> de = dao.getStudentInfo(position);
        EditText stu_id = (EditText) view1.findViewById(R.id.student_id);
        EditText stu_name = (EditText) view1.findViewById(R.id.student_name);
        EditText stu_sex = (EditText) view1.findViewById(R.id.student_sex);
        EditText major_na = (EditText) view1.findViewById(R.id.student_major_name);
        EditText college_na = (EditText) view1.findViewById(R.id.student_college_name);
        EditText tel_number = (EditText) view1.findViewById(R.id.student_tel);
        EditText banji = (EditText) view1.findViewById(R.id.student_banji);
        EditText age=(EditText) view1.findViewById(R.id.student_age);
        edts=new ArrayList<EditText>();
        edts.add(stu_id);
        edts.add(stu_name);
        edts.add(stu_sex);
        edts.add(major_na);
        edts.add(college_na);
        edts.add(tel_number);
        edts.add(banji);
        edts.add(age);
        setEdictale(false);// 无法编译
        ImageView image_title=(ImageView)view1.findViewById(R.id.student_image);
        if(de.get("touxiang_id")!=null&&!de.get("touxiang_id").equals("1")){
            image_title.setImageBitmap(getimage(de.get("touxiang_id")));
        }
        stu_id.setText(de.get("studentid"));
        stu_name.setText(de.get("name"));
        stu_sex.setText(de.get("sex"));
        System.out.println(de.get("age"));
        age.setText(de.get("age"));
        banji.setText(de.get("banji"));
        major_na.setText(de.get("major_na"));
        college_na.setText(de.get("college_na"));
        tel_number.setText(de.get("phone"));
        banji.setText(de.get("banji"));
        alert.show();
    }
});

点击后的程序显示执行效果如下:
注意:在没有上传学生的人脸图像前使用系统初始化图片:此处使用的我自己的偶像—鞠婧祎的照片啦!

android 28天签到功能实现 安卓签到系统_Android api_10


点击显示资料 编译显示 编译完成4.5.3 学生头像上传系统模块:

学生通过学生自己的学号id和密码(初始密码为该学生学号id)进入上传,通过调用本机系统照相机进行拍照人脸或者上传本地相册,然后开启新线程对上传的图片进行比对是否人脸,然后返回一个提醒,如果是人脸那么返回上传成功,如果不是人脸或者其他光线过差等情况则返回一个提示。注意:无论是否上传成功,都会把拍照后的图片保存到本地文件夹下,该文件夹在上传时添加,若不添加则保存到系统根目录下,照片的名字为该学生id.jpg。

学生上传头像主页面: 上传学生人脸选择框:

android 28天签到功能实现 安卓签到系统_Android api_11

上传中:

android 28天签到功能实现 安卓签到系统_Android开发_12

上传过程图:

android 28天签到功能实现 安卓签到系统_上传_13


android 28天签到功能实现 安卓签到系统_Android开发_14


android 28天签到功能实现 安卓签到系统_人脸识别_15

4.5.4 头像验证系统模块:
在头像上传后,我们希望可以通过人脸识别+人脸比对来对同一个学生的不同人脸图片进行人脸识别。通过与上传对图片处理的同样操作,对传入的图片进行放缩+质量压缩转化为Base64Util代码,上传到百度api进行人脸比对,如果在该人脸库就返回签到成功。如果不存在等情况,即返回一个提示信息。如果签到成功,即使该学生的item上的checkbox置为true。

运行状况图:

上传签到人脸,进行人脸识别与该学生的真实人脸进行比对,签到成功效果图

android 28天签到功能实现 安卓签到系统_上传_16