手机端实现图像处理_数字图像处理的数字图像处理的matlab实现 - CSDN
精华内容
参与话题
  • 二、利用JNI将实时图像传到C++进行相关处理 三、在c++部分处理二维物体跟踪用来两个方法互补来保证跟踪的效果: 1 、利用ORB进行物体的特征点的提取 2、 根据ORB提取的特征点进行LK光流跟踪 3、利用BRIFE进行校准-...

    主要思路
    主要分为三步:
    一、调用手机摄像头,获取实时的图像数据
    二、利用JNI将实时图像传到C++端进行相关处理
    三、在c++部分处理二维物体跟踪用来两个方法互补来保证跟踪的效果:
    1 、利用ORB进行物体的特征点的提取
    2、 根据ORB提取的特征点进行LK光流跟踪
    3、利用BRIFE进行校准->如果在校准过程中发现特征点跟踪丢失 或者出现部分特征点出现跟踪缺失的情况,则重新进行ORB对于特征点进行提取

    手机摄像头实时图像获取

    初始化摄像头

     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_camera);
    
            // 动态权限
            if (Build.VERSION.SDK_INT >= buildVersion) {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        requestPermissionId);
            }
    
            // 设置窗口
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    
            // 初始化相机
            mCameraView = findViewById(R.id.cv_camera);
            mCameraView.setVisibility(SurfaceView.VISIBLE);
            mCameraView.setCvCameraViewListener(this);
    
            // 开始预览
            mCameraView.setCameraIndex(0);
            mCameraView.enableView();
            mCameraView.enableFpsMeter();
            // 切换摄像头方法
            RadioButton backOption = findViewById(R.id.backCameraOption);
            backOption.setChecked(true);
            backOption.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cameraId = (cameraId + 1) % 2;
                    cameraSwitch(cameraId);
                }
            });
    
            Switch btHistogram = findViewById(R.id.sw_color1);
            btHistogram.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    process = (process + 1) % 2;
                }
            });
    
    //        Switch btGray = findViewById(R.id.sw_color1);
    //        btGray.setOnClickListener(new View.OnClickListener() {
    //            @Override
    //            public void onClick(View v) {
    //                colorToGray = (colorToGray + 1) % 2;
    //            }
    //        });
        }
    
     对于得到的帧数据进行处理
    
    private Mat process(Mat frame) {
    Bitmap image1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.moss);
              Mat mat1 = new Mat(image1.getHeight()/4,image1.getWidth()/4,CvType.CV_8UC4);
              Utils.bitmapToMat(image1,mat1);
              resize(mat1, mat1, new Size(200,200));
              if(process==1)
            {
                new NDKInterface().trace11(frame.getNativeObjAddr(),mat1.getNativeObjAddr(),mGray.getNativeObjAddr());
                return mGray;
            }
             return frame;
        }
    

    调用摄像头的结果
    在这里插入图片描述

    将获得的实时帧传送到后台C++端处理
    这里的参数 srcAdd指的是实时帧的地址,dstAdd存放的是图片处理结果的地址

    public class NDKInterface {
        static{
            System.loadLibrary("native-lib");
        }
        public native void getEdge(Object bitmap);
        public native int colorToGray(long srcAdd, long dstAdd);
        public native int histogram(long srcAdd,long dstAdd);
        public native int OEBMatch(long srcAdd,long temAdd,long dstAdd);
        public native void tem(long srcAdd,long dstAdd);
        public native void opticalflow(long srcAdd,long dstAdd);
        public native void trace(long srcAdd,long temAdd,long dstAdd);
    
        public native void trace11(long nativeObjAddr, long nativeObjAddr1, long nativeObjAddr2);
        public native void mtf(long nativeObjAddr, long nativeObjAddr1, long nativeObjAddr2);
    
    }
    

    ORB特征点提取以及特征匹配(特征模板与实时帧做匹配)

    vector<Point2f>  match(Mat &img_scene,Mat &dst,Mat &img_object){    //两个图片的特征点提取和特征点匹配
    
        Ptr<ORB> detector = ORB::create();
        std::vector<KeyPoint> keypoints_object, keypoints_scene;
        Mat descriptors_object, descriptors_scene;
        detector->detectAndCompute( img_object, Mat(), keypoints_object, descriptors_object );
        detector->detectAndCompute( img_scene, Mat(), keypoints_scene, descriptors_scene );
        BFMatcher matcher;
        std::vector< DMatch> matches;
        matcher.match(descriptors_object, descriptors_scene, matches);
        double max_dist = 0;
        double min_dist = 100;
        for( int i = 0; i < descriptors_object.rows; i++ )
        { double dist = matches[i].distance;
            if( dist < min_dist ) min_dist = dist;
            if( dist > max_dist ) max_dist = dist;
        }
        std::vector<DMatch> good_matches;
        for( int i = 0; i < descriptors_object.rows; i++ )
        {
            if( matches[i].distance <= 3*min_dist )
            {
                good_matches.push_back( matches[i]);
            }
        }
        Mat img_matches;
        drawMatches( img_object, keypoints_object, img_scene, keypoints_scene,
                     good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                     std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
        std::vector<Point2f> obj;
        std::vector<Point2f> scene;
        for( size_t i = 0; i < good_matches.size(); i++ )
        {
            obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
            scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
        }
        Mat H = findHomography( obj, scene, RANSAC );
        std::vector<cv::Point2f> obj_corners(4);
        obj_corners[0] = cvPoint(0,0);
        obj_corners[1] = cvPoint( img_object.cols, 0 );
        obj_corners[2] = cvPoint( img_object.cols, img_object.rows );
        obj_corners[3] = cvPoint( 0, img_object.rows );
        //std::vector<cv::Point2f> scene_corners(4);
        perspectiveTransform( obj_corners, scene_cornerssss, H);
        line(img_scene, scene_cornerssss[0] , scene_cornerssss[1] , Scalar(0, 255, 0), 4);
        line(img_scene, scene_cornerssss[1] , scene_cornerssss[2] , Scalar(0, 255, 0), 4);
        line(img_scene, scene_cornerssss[2] , scene_cornerssss[3] , Scalar(0, 255, 0), 4);
        line(img_scene, scene_cornerssss[3] , scene_cornerssss[0] , Scalar(0, 255, 0), 4);
        return scene;
    
    }
    

    LK光流

    /光流法 实现跟踪
    JNIEXPORT void JNICALL
    Java_com_example_bymyself_NDKInterface_opticalflow(JNIEnv *env, jobject thiz, jlong src_add,
                                                       jlong dst_add) {
        // TODO: implement opticalflow()
        Mat &frame = *(Mat *) src_add;  //输入的帧frame(手机摄像头获得的图像信息)
        Mat &output = *(Mat *) dst_add; //输出的帧(处理以后画出跟踪的帧)
        //此句代码的OpenCV3版为:
        cvtColor(frame, gray, COLOR_BGR2GRAY);
        frame.copyTo(output);
        // 添加特征点(得到可以跟踪的点)
        if (addNewPoints())
        {
            goodFeaturesToTrack(gray, features, maxCount, qLevel, minDist);      //得到可以跟踪的点,结果放在features之中
            points[0].insert(points[0].end(), features.begin(), features.end()); //points[0]是特征点原来的位置,将可以跟踪的点放入特征点原来的特征点的集合之中
            initial.insert(initial.end(), features.begin(), features.end());     //同理 对初始跟踪点也做相应操作
        }
        if (gray_prev.empty())                                                   //判断一下预测的图片是否为空
        {
            gray.copyTo(gray_prev);                                              //如果为空就将初始的图片赋值给预测的图片
        }
        // L-k光流法运动估计
        calcOpticalFlowPyrLK(gray_prev, gray, points[0], points[1], status, err);  //进行L-K光流法的运动估计
        // 去掉一些不好的特征点
        int k = 0;
        for (size_t i = 0; i < points[1].size(); i++)
        {
            if (acceptTrackedPoint(i))
            {
                initial[k] = initial[i];
                points[1][k++] = points[1][i];
            }
        }
        points[1].resize(k);
        initial.resize(k);
        // 显示特征点和运动轨迹
        for (size_t i = 0; i < points[1].size(); i++)
        {
            line(output, initial[i], points[1][i], Scalar(0, 0, 255));
            circle(output, points[1][i], 3, Scalar(0, 255, 0), -1);
        }
    
        // 把当前跟踪结果作为下一次的参考
        swap(points[1], points[0]);
        swap(gray_prev, gray);
    }
    

    两者判断效果好坏,做结果分析

    JNIEXPORT void JNICALL
    Java_com_example_bymyself_NDKInterface_trace(JNIEnv *env, jobject thiz, jlong src_add, jlong tem_add,
                                                 jlong dst_add) {
        Mat &frame = *(Mat *) src_add;
        Mat &output = *(Mat *) dst_add;
        Mat &img_object = *(Mat *) tem_add;
        if (ready == true) {
            feats = match(frame, output, img_object);
            ready = false;
        } else {
            cvtColor(frame, gra, COLOR_BGR2GRAY);
            frame.copyTo(output);
            if (addNewPoint()) {
                pq[0].insert(pq[0].end(), feats.begin(),feats.end());    //points[0]是特征点原来的位置,将可以跟踪的点放入特征点原来的特征点的集合之中
                init.insert(init.end(), feats.begin(), feats.end());     //同理 对初始跟踪点也做相应操作
            }
            if (g_prev.empty())                                                   //判断一下预测的图片是否为空
            {
                gra.copyTo(g_prev);                                              //如果为空就将初始的图片赋值给预测的图片
            }
            calcOpticalFlowPyrLK(g_prev, gra, pq[0], pq[1], stat, err);  //进行L-K光流法的运动估计,跟踪内部的点
            calcOpticalFlowPyrLK(g_prev, gra, scene_cornerssss, site[0], stat1, err);   //跟踪模板的边界点
            if(flag)
            {
                good[0] = scene_cornerssss;
                flag = false;
                LOGD("4444444444444444444444444444444 is finished");
            }
    
            int k = 0;
            for (size_t i = 0; i < pq[1].size(); i++) {
                if (acceptTrackedPointss(i)) {
                    init[k] = init[i];
                    pq[1][k++] = pq[1][i];
                }
            }
            pq[1].resize(k);
            init.resize(k);
            //显示特征点和运动轨迹
            for (size_t i = 0; i < pq[1].size(); i++) {
                line(output, init[i], pq[1][i], Scalar(0, 0, 255));
                circle(output, pq[1][i], 3, Scalar(0, 255, 0), -1);
            }
            for(int i = 0;i < 4;i++)
            {
                if(stat1[i]== 0)
                    flags = false;
            }
            if (!getN(frame,img_object,good[0],site[0])&&flags) {              //good[0]表示最好的匹配结果 site[0]表示跟踪的结果
                line(output, site[0][0], site[0][1], Scalar(0, 255, 0), 4);
                line(output, site[0][1], site[0][2], Scalar(0, 255, 0), 4);
                line(output, site[0][2], site[0][3], Scalar(0, 255, 0), 4);
                line(output, site[0][3], site[0][0], Scalar(0, 255, 0), 4);
                // 把当前跟踪结果作为下一次的参考
                feats = pq[1];
                scene_cornerssss = site[0];
                swap(pq[1], pq[0]);
                swap(g_prev, gra);
                LOGD("55555555555555555555555555555555555555555 is finished");
            } else
            {
                line(output, site[0][0], site[0][1], Scalar(0, 255, 0), 4);
                line(output, site[0][1], site[0][2], Scalar(0, 255, 0), 4);
                line(output, site[0][2], site[0][3], Scalar(0, 255, 0), 4);
                line(output, site[0][3], site[0][0], Scalar(0, 255, 0), 4);
                LOGD("6666666666666666666666666666666666666666666666 is finished");
            }
        }
    }
    
    

    在这里插入图片描述

    展开全文
  • 使用WebRTC实现电脑与手机通过浏览器进行视频通话

    万次阅读 多人点赞 2013-08-17 21:43:46
    下面是手机和电脑进行视频聊天的截图:PC端手机端我的测试环境:PC端:Chrome 28手机端:GalaxyS2 Android4.03 浏览器Chrome Beta好像目前手机上只有Chrome Beta支持WebRTC测试的时候遇到一个问题,就是发热很严重

          最近一直在研究WebRTC,做了一个小项目:www.meet58.com,这个项目利用WebRTC、WebSocket可以让各种设备只通过浏览器进行视频聊天,无论是电脑、手机或者是平板。下面就是手机和电脑进行视频通话的截图:


    PC端


    手机端

    这个项目目前只有简单的视频通话功能,后期陆续开发桌面共享、录制视频、录制音频及照片处理等功能。


    我的测试环境:

    PC端:Chrome 28

    手机端:GalaxyS2 Android4.03 浏览器Chrome Beta

    好像目前手机上只有Chrome Beta支持WebRTC

    测试的时候遇到一个问题,就是发热很严重


    展开全文
  • 图像处理】图像算法开发过程

    千次阅读 2015-12-16 22:33:57
    图像算法开发跟普通程序的软件算法开发又不一样,图像算法主要是关注如何对图像进行处理,也就是关注的优化的对象不一样。图像算法开发过程,一般是: 1)在PC进行算法验证,达到所要实现的功能。 2)算法移植到...

    最近刚接触图像算法开发,而且也是手机端的图像算法开发,一上来导师就给说说图像算法开发的过程。

    图像算法开发跟普通程序的软件算法开发又不一样,图像算法主要是关注如何对图像进行处理,也就是关注的优化的对象不一样。

    图像算法开发过程,一般是:
    1)在PC端进行算法验证,达到所要实现的功能。因为在PC端能够更好的进行算法调试,确保功能实现。
    2)PC端的优化,将算法优化到最佳状态。
    3)算法移植到手机平台上,实现算法功能。
    4)移动端算法优化,进行C/C++代码优化,NEON优化等等。后续将对如何进行代码优化进行总结。

    在整个过程中,对算法的理解十分重要,而如何进行代码优化,NEON优化是算法实现的难点。

    后续通过各种算法的实践、联系、总结,不断的加深理解。

    展开全文
  • 树莓派笔记15:手机控制树莓派小车

    万次阅读 多人点赞 2018-09-01 12:03:53
    树莓派小车由树莓派、小车地盘、电机及电机控制模块、摄像头、舵机云台和OLED显示屏等组成,手机端写了一个简单的App,可以控制小车的行进,控制摄像头云台转动,同时可以接收显示摄像头的图像。 小车图片: ...

    1 成果展示

    花了点时间做了简单的手机控制树莓派小车项目,其实主要是对之前各种学习内容的一个综合利用,也特地抽出时间学习了一下最基本的Android开发。下面的图片是成果的展示,树莓派小车由树莓派、小车地盘、电机及电机控制模块、摄像头、舵机云台和OLED显示屏等组成,手机端写了一个简单的App,可以控制小车的行进,控制摄像头云台转动,同时可以接收显示摄像头的图像。

    小车图片:
    小车
    这里写图片描述
    这里写图片描述

    手机App,左边的方向按钮控制电机运动,右边的方向按钮控制云台转动:
    这里写图片描述

    演示:
    这里写图片描述

    2 简要说明

    1 用到哪些硬件模块

    购买现成的小车底座,包括电机马达和车轮;
    使用L298N模块来控制小车底座上的电机,使树莓派可以驱动小车运动;
    一块12V的锂电池,专门给L298N供电;
    树莓派专用CSI接口摄像头,用来采集图像;
    由两个SG90舵机构成的云台,作为摄像头的搭载平台;
    一块OLED显示屏,简要地显示一些信息;
    不用的一个充电宝,用来给树莓派供电;
    自己的Android手机

    2 程序开发说明

    树莓派上写python脚本来运行,手机上用Android Studio开发App;
    树莓派上的python应用不是完全写在一个程序文件内的,所以用了一个bash脚本来统一启动或停止多个python程序;
    为不同的硬件模块写运行脚本,需要安装、导入一些第三方库;
    对于图像的采集,我使用的是OpenCV库,简单地捕获图像帧再编码发送,接收端解码后显示出图片;
    手机与树莓派在同一个局域网下通过TCP或UDP进行通信。手机用TCP向树莓派发送控制指令;树莓派通过UDP传送图像

    3 存在的问题

    如果没有后续的图像处理操作的话,用OpenCV来捕获摄像头图像有点杀鸡用牛刀,因为OpenCV比较庞大,安装起来很费劲。对于树莓派专用摄像头,可以使用picamera库;
    直接用UDP传输捕获到的图片,虽然实现简单,但对网络要求较高,所以小车和手机需要处在网络良好的局域网下,并且要对图片做较大的压缩;
    启动程序需要SSH登陆后手动运行,可以做成自启动或者外接开关进行控制

    3 源码地址

    树莓派端:
    https://github.com/RyanWang20180512/RaspberrryPi-Project-for-PiCar.git
    手机端:
    https://github.com/RyanWang20180512/Cellphone-control-project-for-Picar.git

    展开全文
  • 响应式Web设计之初探图像处理

    万次阅读 2012-08-10 11:28:08
    在我上一篇的博文“什么是移动优先的响应式Web设计”中,我提到了一个用来判别一个响应式Web设计是否是“移动优先”的标准,即这个设计是否有处理IMG标签的策略。 最近在国外关于一个Web设计的网站Smashing ...
  • 关于直播类app中的推流、拉流技术

    千次阅读 2019-04-11 15:34:03
    关于直播类app中的推流、拉流...图像处理:iOS一般会用到GPUImage处理图像,安卓一般使用Google的grafika(图形处理库) 推拉流:EasyDarwin 推流:【iOS和Android】ijkPlayer 开源框架(bilibili的)(集成了FFmp...
  • 摘要:基于Android 4.2的WiFidirect功能实现WiFidisplay 的sink系统,sink通过与source进行capatibility negotiation确定两者能共同支持的最高解码音视频格式。基于这套格式,sink接收source传递的流媒体...
  • Android手机视频监控系统

    千次阅读 2017-05-14 14:01:44
    前言:该系统分为手机端和后台服务器端,创作于前几年,当时采用的开发环境(adk、opencv等)现在可能已经变更好几代了,有需要的童鞋可以作为学习的素材下载来研究改进。 Android手机视频监控系统   1.1实现...
  • ESP32 开发笔记(四)OV7670 摄像头图像采集

    万次阅读 热门讨论 2020-07-23 15:03:03
    ESP32 Camera Demo ...使用的硬件有: - ESP-WROVER-KIT开发板 - OV7670 摄像头 - ST7789 控制器的 LCD 屏幕 该工程实现的功能有: - 通过手机端浏览器访问 ESP32 HTTP 服务器,查看当前摄像头采集的图像 - 摄
  • 前几篇文章分别阐述了如何抓取windows桌面图像,以及相关摄像头,电脑内部声音等采集,相关连接如下: http://blog.csdn.net/fanxiushu/article/details/73269286 (抓屏技术总览 MirrorDriver,DXGI,GDI) ...
  • Learn to See in the Dark 论文解读

    万次阅读 2018-05-12 15:40:23
    整理下最近一篇论文的学习笔记。这是由UIUC的陈晨和Intel Labs的陈启峰、许佳、Vladlen Koltun 合作提出的一种在黑暗中也能快速、清晰的成像系统,让机器“看破”...目前,很多关于去噪、去模糊、图像增强等技术的...
  • 无人机系列之图传技术

    万次阅读 2017-02-09 10:05:35
    2016年,是中国无人机市场的元年,无人机能够一跃进入大众视野,并迅速在大众市场火热发展,是很多人始料未及的。从刚开始的空中摄录,到后来的实时...专业的航空航天器并没有独立的视频图像传输设备。图传的概念只存在
  • 移动端直播的几种方案

    千次阅读 2017-08-14 15:32:54
    本文中主要简单实现了三种视频直播的方法,并对视频直播方案做了一个总结。主要包含: RMTP + Nginx + HLS Node.js + WebSocket + canvas flv.js + WebView 1.直播流程直播主要分为三个部分,视频
  • 今天做手机网站,想实现手机...首先实现在浏览器中调用手机摄像头,实现拍照功能并且把拍下的照片显示在页面并上传到服务器上,然后再在服务器进行分析。 首先实现在浏览器中调用摄像头,当然用现在火的不行
  • 更周全的做法提前加载自定义触发事件自定义显示效果把图像插入某个容器加载不可见图像 WPJAM TOC Lazy Load 这个 jQuery 插件,是用来缓冲加载图片的插件。如果一篇文章很长有很多图片的话,下载图片就需要很多...
  • USB Video Class及其实现

    千次阅读 2010-09-19 21:45:00
    1 Video Class 基础概念 Usb协议中,除了通用的软硬件电气接口规范等,还包含了各种各样的Class协议,用来为不同...  理论上说,即使没有这些Class,通过专用驱动也能够实现各种各样的应用功能。但是,正如M
  • 目录 ISP的主要内部构成:ISP内部包含 CPU、SUP IP(各种功能模块的通称)、IF 等设备 ISP的控制结构:1、ISP逻辑 2、运行在其上的firmware ISP上的Firmware包含三部分: ...ISP 处理流程: Bayer、黑电平补偿(...
  • 关键字:安卓设备,图像处理 GitHub链接:这里 跳一跳的外挂在前一阵子非常火,甚至有些全工科狂欢的势头。从最开始的图像识别法、伪造数据包法,到后来的图像识别法、甚至OpenCL+机械手臂模拟法,可谓八仙过海...
  • 相机系统综述 —— ISP

    千次阅读 2016-11-15 16:27:09
    ISP(Image Signal Processor),即图像信号处理器,用于处理图像信号传感器输出的图像信号。它在相机系统中占有核心主导的地位,是构成相机的重要设备。 主要内部构成 如下图所示,ISP 内部包含 CPU、SUP IP、...
  • MIPI CSI2学习(一):说一说MIPI CSI2

    万次阅读 多人点赞 2018-08-16 15:42:24
    1. MIPI CSI2简介   MIPI联盟是一个开放的会员制组织。...MIPI联盟下面有不同的WorkGroup,分别定义了一系列的手机内部接口标准,比如摄像头接口CSI、显示接口DSI、射频接口DigRF、麦克风/喇叭接口SL...
1 2 3 4 5 ... 20
收藏数 20,665
精华内容 8,266
关键字:

手机端实现图像处理