zoukankan      html  css  js  c++  java
  • Android OpenCV集成摄像头图片动态识别车牌号

      最近两天开发一个使用OpenCV集成的一个识别车牌号的项目,困难重重,总结一下相关经验,以及开发注意事项;

    一、开发环境:

         Android Studio 个人版本 3.1.4

         NDK下载:14b

         CMake:Android Studio SDK Tools中下载

         参考资料:https://github.com/zeusees/HyperLPR   集成有冲突未解决;

                        很实用的一个Dmeo以这个为例

                        https://blog.csdn.net/u011686167/article/details/79029765   

                        楼主人很好,给我解答疑问;附上博主Demo下载地址:

                        https://download.csdn.net/download/u011686167/10899892

         集成中遇到的问题:

         一、环境配置的问题:

               NDK:尝试使用最新版本,但是一直有冲突,出现问题,14b使用兼容性比较好

               CMake:

               OpenCV类库: openCVLibrary330

         二、项目集成问题:

             (1)下载模型文件替换和倒入assets/pr下面的文件,报错如下:

                "/storage/emulated/0/pr/HorizonalFinemapping.prototxt") in bool cv::dnn::ReadProtoFromTextFile(

                 const char*,google::protobuf::Message*), file /build/master_pack-android/opencv/modules/dnn/src

                /caffe/caffe_io.cpp, line 1113

               (2)添加摄像头权限

               (3)问题:只能横向识别车牌号,纵向不能识别,并且相机方向不对:

                 解决相机显示正常:

                 参考资料   https://blog.csdn.net/u010112268/article/details/80420454               

                 将下图文件中的  deliverAndDrawFrame 方法

                  

                  修改为以下:

    protected void deliverAndDrawFrame(CvCameraViewFrame frame){
        Mat modified;
    
        if (mListener != null) {
            modified = mListener.onCameraFrame(frame);
        } else {
            modified = frame.rgba();
        }
    
        boolean bmpValid = true;
        if (modified!= null) {
            try {
                Utils.matToBitmap(modified,mCacheBitmap);
            } catch(Exceptione) {
                Log.e(TAG, "Mattype: " + modified);
                Log.e(TAG, "Bitmaptype: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());
                Log.e(TAG, "Utils.matToBitmap()throws an exception: " +e.getMessage());
                bmpValid = false;
            }
        }
    
        if (bmpValid&& mCacheBitmap != null) {
            Canvas canvas =getHolder().lockCanvas();
            if (canvas!= null) {
                canvas.drawColor(0,android.graphics.PorterDuff.Mode.CLEAR);
                /*if (BuildConfig.DEBUG)
                    Log.d(TAG, "mStretchvalue: " + mScale);
    
                if (mScale != 0) {
                   canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(),mCacheBitmap.getHeight()),
                         newRect((int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2),
                        (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2),
                         (int)((canvas.getWidth() -mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth()),
                        (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2 +mScale*mCacheBitmap.getHeight())), null);
                } else {
                    canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(),mCacheBitmap.getHeight()),
                         newRect((canvas.getWidth() - mCacheBitmap.getWidth()) / 2,
                         (canvas.getHeight()- mCacheBitmap.getHeight()) / 2,
                         (canvas.getWidth() -mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth(),
                         (canvas.getHeight()- mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight()), null);
                }*/
    
                /*----------------------------修改预览旋转90度问题--------------------------------*/
                canvas.rotate(90,0,0);
                float scale= canvas.getWidth() / (float)mCacheBitmap.getHeight();
                float scale2= canvas.getHeight() / (float)mCacheBitmap.getWidth();
                if(scale2> scale){
                    scale = scale2;
                }
                if (scale!= 0) {
                    canvas.scale(scale,scale,0,0);
                }
                canvas.drawBitmap(mCacheBitmap, 0, -mCacheBitmap.getHeight(), null);
                /*----------------------------修改预览旋转90度问题--------------------------------*/
    
                if (mFpsMeter != null) {
                    mFpsMeter.measure();
                    mFpsMeter.draw(canvas, 20, 30);
                }
                getHolder().unlockCanvasAndPost(canvas);
            }
        }
    
    }
    

         

             解决图片不能纵向识别方法:参考资料 https://blog.csdn.net/hujiameihuxu/article/details/78810100

              图片角度转换:

    Mat matRotateClockWise90(Mat src)
    {
    	if (src.empty())
    	{
    		qDebug()<<"RorateMat src is empty!";
    	}
    	// 矩阵转置
    	transpose(src, src);
    	//0: 沿X轴翻转; >0: 沿Y轴翻转; <0: 沿X轴和Y轴翻转
    	flip(src, src, 1);// 翻转模式,flipCode == 0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)
    	return src;
    }
     
    Mat matRotateClockWise180(Mat src)//顺时针180
    {
    	if (src.empty())
    	{
    		qDebug() << "RorateMat src is empty!";
    	}
    	
    	//0: 沿X轴翻转; >0: 沿Y轴翻转; <0: 沿X轴和Y轴翻转
    	flip(src, src, 0);// 翻转模式,flipCode == 0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)
    	flip(src, src, 1);
    	return src;
    	//transpose(src, src);// 矩阵转置
    }
     
    Mat matRotateClockWise270(Mat src)//顺时针270
    {
    	if (src.empty())
    	{
    		qDebug() << "RorateMat src is empty!";
    	}
    	// 矩阵转置
    	//transpose(src, src);
    	//0: 沿X轴翻转; >0: 沿Y轴翻转; <0: 沿X轴和Y轴翻转
    	transpose(src, src);// 翻转模式,flipCode == 0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)
    	flip(src, src, 0);
    	return src;
    }
     
    Mat myRotateAntiClockWise90(Mat src)//逆时针90°
    {
    	if (src.empty())
    	{
    	  qDebug()<<"mat is empty!";
    	}
    	transpose(src, src);
    	flip(src, src, 0);
    

      进行转化:

        

      本人Demo代码地址以及模型地址:https://gitee.com/anan9303/PrjAndroid.git

               

  • 相关阅读:
    使用 SQL Server 2008 数据类型-xml 字段类型参数进行数据的批量选取或删除数据
    启用Windows 7/2008 R2 XPS Viewer
    Office 2010培训资料
    WCF WebHttp Services in .NET 4
    ASP.NET MVC 2示例Tailspin Travel
    .NET 4.0 的Web Form和EF的例子 Employee Info Starter Kit (v4.0.0)
    连任 2010 年度 Microsoft MVP
    MIX 10 Session下载
    Microsoft Silverlight Analytics Framework
    Windows Azure入门教学
  • 原文地址:https://www.cnblogs.com/huihuizhang/p/10720978.html
Copyright © 2011-2022 走看看