实时图像处理_水下实时图像处理 - CSDN
精华内容
参与话题
  • Python+OpenCV实时图像处理

    万次阅读 多人点赞 2020-10-17 09:20:23
    初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试有一定帮助。

    目录

    1、导入库文件

    2、设计GUI

    3、调用摄像头

    4、实时图像处理

    4.1、阈值二值化

    4.2、边缘检测

    4.3、轮廓检测

    4.4、高斯滤波

    4.5、色彩转换

    4.6、调节对比度

    5、退出系统


    初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试有一定帮助。

    1、导入库文件

    这里主要使用PySimpleGUI、cv2和numpy库文件,PySimpleGUI库文件实现GUI可视化,cv2库文件是Python的OpenCV接口文件,numpy库文件实现数值的转换和运算,均可通过pip导入。

    import PySimpleGUI as sg  #pip install pysimplegui
    import cv2  #pip install opencv-python
    import numpy as np #pip install numpy

    2、设计GUI

    基于PySimpleGUI库文件实现GUI设计,本项目界面设计较为简单,设计800X400尺寸大小的框图,浅绿色背景,主要由摄像头界面区域和控制按钮区域两部分组成。效果如下所示:

    GUI代码如下所示:

        #背景色
        sg.theme('LightGreen')
    
        #定义窗口布局
        layout = [
          [sg.Image(filename='', key='image')],
          [sg.Radio('None', 'Radio', True, size=(10, 1))],
          [sg.Radio('threshold', 'Radio', size=(10, 1), key='thresh'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(40, 15), key='thresh_slider')],
          [sg.Radio('canny', 'Radio', size=(10, 1), key='canny'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='canny_slider_a'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='canny_slider_b')],
          [sg.Radio('contour', 'Radio', size=(10, 1), key='contour'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='contour_slider'),
           sg.Slider((0, 255), 80, 1, orientation='h', size=(20, 15), key='base_slider')],
          [sg.Radio('blur', 'Radio', size=(10, 1), key='blur'),
           sg.Slider((1, 11), 1, 1, orientation='h', size=(40, 15), key='blur_slider')],
          [sg.Radio('hue', 'Radio', size=(10, 1), key='hue'),
           sg.Slider((0, 225), 0, 1, orientation='h', size=(40, 15), key='hue_slider')],
          [sg.Radio('enhance', 'Radio', size=(10, 1), key='enhance'),
           sg.Slider((1, 255), 128, 1, orientation='h', size=(40, 15), key='enhance_slider')],
          [sg.Button('Exit', size=(10, 1))]
        ]
    
        #窗口设计
        window = sg.Window('OpenCV实时图像处理',
                   layout,
                   location=(800, 400),
                   finalize=True)

    3、调用摄像头

    打开电脑内置摄像头,将数据显示在GUI界面上,效果如下所示:

    代码如下所示:

        #打开内置摄像头
        cap = cv2.VideoCapture(0)
        while True:
            event, values = window.read(timeout=0, timeout_key='timeout')
    
            #实时读取图像
            ret, frame = cap.read()
    
            #GUI实时更新
            imgbytes = cv2.imencode('.png', frame)[1].tobytes()
            window['image'].update(data=imgbytes)
    
        window.close()

    4、实时图像处理

    4.1、阈值二值化

    进行阈值二值化操作,大于阈值values['thresh_slider']的,使用255表示,小于阈值values['thresh_slider']的,使用0表示,效果如下所示:

     代码如下所示:

    if values['thresh']:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)[:, :, 0]
        frame = cv2.threshold(frame, values['thresh_slider'], 255, cv2.THRESH_BINARY)[1]

    4.2、边缘检测

    进行边缘检测,values['canny_slider_a']表示最小阈值,values['canny_slider_b']表示最大阈值,效果如下所示:

    代码如下所示:

    if values['canny']:
        frame = cv2.Canny(frame, values['canny_slider_a'], values['canny_slider_b'])

    4.3、轮廓检测

    轮廓检测是形状分析和物体检测和识别的有用工具,连接所有连续点(沿着边界)的曲线,具有相同的颜色或强度,效果如下所示:

     代码如下所示:

    if values['contour']:
        hue = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        hue = cv2.GaussianBlur(hue, (21, 21), 1)
        hue = cv2.inRange(hue, np.array([values['contour_slider'], values['base_slider'], 40]),
                          np.array([values['contour_slider'] + 30, 255, 220]))
        cnts= cv2.findContours(hue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
        cv2.drawContours(frame, cnts, -1, (0, 0, 255), 2)
    

    4.4、高斯滤波

    进行高斯滤波,(21, 21)表示高斯矩阵的长与宽都是21,标准差取values['blur_slider'],效果如下所示:

     代码如下所示:

    if values['blur']:
        frame = cv2.GaussianBlur(frame, (21, 21), values['blur_slider'])
    

    4.5、色彩转换

    色彩空间的转化,HSV转换为BGR,效果如下所示:

     代码如下所示:

    if values['hue']:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        frame[:, :, 0] += int(values['hue_slider'])
        frame = cv2.cvtColor(frame, cv2.COLOR_HSV2BGR)

    4.6、调节对比度

    增强对比度,使图像中的细节看起来更加清晰,效果如下所示:

      代码如下所示:

    if values['enhance']:
        enh_val = values['enhance_slider'] / 40
        clahe = cv2.createCLAHE(clipLimit=enh_val, tileGridSize=(8, 8))
        lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)
        lab[:, :, 0] = clahe.apply(lab[:, :, 0])
        frame = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
    

    5、退出系统

    直接break即可跳出循环。

    if event == 'Exit' or event is None:
        break

    拓展学习:基于Python的人工智能美颜系统 

    请关注公众号,回复关键字:OpenCV实时图像处理,获取项目资源。

    展开全文
  • MATLAB摄像头实时图像处理

    千次阅读 多人点赞 2020-09-04 13:54:21
    之前由于双目测距的工作,用MATLAB获取摄像头数据并实时处理。现将一些基本操作分享给大家。欢迎交流


    by HPC_ZY


    第一步:安装硬件支持包

    1. 打开附加功能项
      在这里插入图片描述
    2. 查找如下摄像头支持包在这里插入图片描述

    第二步:获取摄像头信息

    1. 输入 imaqhwinfo,查看当前适配器
      在这里插入图片描述
      如图,我们的适配器名为 winvideo

    2. 输入imaqhwinfo(‘winvideo’),查看该适配器下所有设备

    在这里插入图片描述
    由于没有接入USB摄像头,当前只有笔记本电脑自带的摄像头

    1. 通过DeviceInfo查看摄像头详细信息
      在这里插入图片描述
      其中 SupportedFormats是该摄像头支持的图像色彩与尺寸,我的设备如下:
      在这里插入图片描述

    2. 上述代码

    % 查看适配器
    disp(imaqhwinfo)
    % 查看设备及其支持的格式
    info = imaqhwinfo('winvideo');
    disp(info.DeviceInfo.SupportedFormats)
    
    

    第三步:数据实时处理

    有了前面的准备,就可以正式开始了。

    1. 连接摄像头获取数据
    % 生成对象并同步画面
    obj = videoinput('winvideo',1,'MJPG_640x480);
    h = preview(obj);
    
    

    运行代码会弹出以下界面,实时画面在这里插入图片描述

    1. 导出图像数据
      利用此函数 getsnapshot(obj) 即可导出图像,若想连续导出可通过以下方式
    figure
    while ishandle(h)
        frame = getsnapshot(obj);  % 获取帧
        imshow(frame)
        drawnow
    end
    
    

    注:
    (1)帧率跟电脑配置有关,在当前尺寸下我只能达到10帧;
    (2)通常直接使用MJPG格式,如果需要使用YUY2格式,在显示时用 ycbcr2rgb()将其改为RGB即可。

    1. 实时图像处理:简单边缘提取
      只需在上述代码中稍作修改
    figure
    while ishandle(h)
        frame = getsnapshot(obj);  % 获取帧
        % -----------此处可添加你需要的操作------------
        imedge = edge(rgb2gray(imedge),'log') % 计算log边缘
        % -------------------------------------------
        subplot(121),imshow(frame)
        subplot(122),imshow(imedge)
        drawnow
    end
    

    效果图如下(由于太懒没有制作动图,仅截图示意,大家可自行测试)
    在这里插入图片描述

    最后

    在此基础上,就可以进行更多高级操作,如:目标检测、运动追踪、双目测距……

    有任何问题欢迎讨论,最后还是把测试代码上传
    https://download.csdn.net/download/xsz591541060/11152130
    由于很简单,不推荐下载,除非你买了年VIP。

    展开全文
  • 在上篇中我们已经实现了相机打开和实时图像信息的获取,那么接下来我们可以尝试在获取的图像信息进行一些处理,然后实时显示出来,在这里我们要完成的的几种处理:  灰化、Canny边缘检测、Hist直方图计算、Sobel...

            在上篇中我们已经实现了相机打开和实时图像信息的获取,那么接下来我们可以尝试在获取的图像信息进行一些处理,然后实时显示出来,在这里我们要完成的的几种处理:

            灰化、Canny边缘检测、Hist直方图计算、Sobel边缘检测、SEPIA(色调变换)、ZOOM放大镜、PIXELIZE像素化


    一、修改布局界面:

            由于这里我们需要切换不同的图像处理模式,所以这里我们需要在界面上放置一个按钮,我们可以放置很多个按钮,每个按钮对应一种处理模式,但是这里我们也可以只放置一个按钮,每次点击按钮就切换一次,循环切换模式:

            activity_main.xml文件:

    <FrameLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:opencv="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <org.opencv.android.JavaCameraView 
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/camera_view"
            opencv:show_fps="true" 
            opencv:camera_id="any"/>
        
        <RelativeLayout 
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="bottom|center_horizontal">
            <Button 
                android:id="@+id/deal_btn"
                android:layout_width="100dp"
                android:layout_height="40dp"
                android:layout_marginBottom="20dp"
                android:text="处理"/>
        </RelativeLayout>
    
    </FrameLayout>
            查看预览图:
            

    二、获取按钮组件并监听按钮点击:

    1.声明一个Button对象用于绑定上面的按钮组件和一个状态标志位用于存储当前状态:

            //按钮组件
    	private Button mButton;
    	//当前处理状态
    	private static int Cur_State = 0;


    2.在OnCreate中绑定按钮和按钮点击监听:

    mButton = (Button) findViewById(R.id.deal_btn);
    mButton.setOnClickListener(new OnClickListener(){
    	@Override
    	public void onClick(View v) {
    		if(Cur_State<8){
    			//切换状态
    			Cur_State ++;
    		}else{
    			//恢复初始状态
    			Cur_State = 0;
    		}
    	}
    			
    });
            这里的状态标志位Cur_State与图像处理的每个类型对应,0对应默认状态,也就是显示原图,1-7分别对应:灰化、Canny边缘检测、Hist直方图计算、Sobel边缘检测、SEPIA(色调变换)、ZOOM放大镜、PIXELIZE像素化

    三、图像信息获取保存、处理和显示:

    1.在OpenCV中一般都是使用Mat类型来存储图像等矩阵信息,所以我们可以声明一个Mat对象用来作为实时帧图像的缓存对象:

    //缓存相机每帧输入的数据
    private Mat mRgba;


    2.对象实例化以及基本属性的设置,包括:长度、宽度和图像类型标志:
    public void onCameraViewStarted(int width, int height) {
    	// TODO Auto-generated method stub
    	mRgba = new Mat(height, width, CvType.CV_8UC4);
    }


    3.对象赋值,这里只对原图和灰化两种情况进行了处理,其他的处理后续再添加:

            /**
    	 * 图像处理都写在此处
    	 */
    	@Override
    	public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    		switch (Cur_State) {
    		case 1:
    			//灰化处理
    			Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA,4);
    			break;
    		default:
    			//显示原图
    			mRgba = inputFrame.rgba();
    			break;
    		}
    		//返回处理后的结果数据
    		return mRgba;
    	}


    4.由于用对象存储图像数据的话,数据会保存到内存中,所以结束的时候需要进行数据释放,不然可能导致崩溃:

            @Override
    	public void onCameraViewStopped() {
    		// TODO Auto-generated method stub
    		mRgba.release();
    	}

    5.运行查看效果:

            正常模式:

            
            灰化图:

            


    四、其他处理及结果:

            在以上的例子中我们已经完成了预览图的灰化处理,那么接下来我们把其他处理都添加到代码中,查看效果。由于在2.x版本中使用到的部分方法已经发生了变化,如:在OpenCV 3.1.0中org.opencv.core.Core类中的方法line和rectangle都已失效,可以用org.opencv.imgproc.Imgproc中的line和rectangle来代替:

    1. MainActivity.java源码:

    package com.linsh.opencv_test;
    
    import java.util.Arrays;
    
    import org.opencv.android.BaseLoaderCallback;
    import org.opencv.android.CameraBridgeViewBase;
    import org.opencv.android.OpenCVLoader;
    import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
    import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
    import org.opencv.android.LoaderCallbackInterface;
    import org.opencv.core.Core;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    import org.opencv.core.MatOfFloat;
    import org.opencv.core.MatOfInt;
    import org.opencv.core.Point;
    import org.opencv.core.Scalar;
    import org.opencv.core.Size;
    import org.opencv.imgproc.Imgproc;
    
    import android.R.string;
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.Button;
    import android.view.View;
    import android.view.View.OnClickListener;
    
    public class MainActivity extends Activity implements CvCameraViewListener2{
    	private String TAG = "OpenCV_Test";
    	//OpenCV的相机接口
    	private CameraBridgeViewBase mCVCamera;
    	//缓存相机每帧输入的数据
    	private Mat mRgba,mTmp;
    	//按钮组件
    	private Button mButton;
    	//当前处理状态
    	private static int Cur_State = 0;
    	
    	private Size mSize0;
        private Mat mIntermediateMat;
        private MatOfInt mChannels[];
        private MatOfInt mHistSize;
        private int mHistSizeNum = 25;
        private Mat mMat0;
        private float[] mBuff;
        private MatOfFloat mRanges;
        private Point mP1;
        private Point mP2;
        private Scalar mColorsRGB[];
        private Scalar mColorsHue[];
        private Scalar mWhilte;
        private Mat mSepiaKernel;
    	
    	/**
    	 * 通过OpenCV管理Android服务,异步初始化OpenCV
    	 */
    	BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    		@Override
    		public void onManagerConnected(int status){
    			switch (status) {
    			case LoaderCallbackInterface.SUCCESS:
    				Log.i(TAG,"OpenCV loaded successfully");
    				mCVCamera.enableView();
    				break;
    			default:
    				break;
    			}
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    		mCVCamera = (CameraBridgeViewBase) findViewById(R.id.camera_view);
    		mCVCamera.setCvCameraViewListener(this);
    		
    		mButton = (Button) findViewById(R.id.deal_btn);
    		mButton.setOnClickListener(new OnClickListener(){
    			@Override
    			public void onClick(View v) {
    				if(Cur_State<8){
    					//切换状态
    					Cur_State ++;
    				}else{
    					//恢复初始状态
    					Cur_State = 0;
    				}
    			}
    			
    		});
    	}
    	
    	@Override
    	public void onResume() {
    		super.onResume();
    		if (!OpenCVLoader.initDebug()) {
    			Log.d(TAG,"OpenCV library not found!");
    		} else {
    			Log.d(TAG, "OpenCV library found inside package. Using it!");
    			mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    		}
    	};
    	
    	@Override
    	public void onDestroy() {
    		if(mCVCamera!=null){
    			mCVCamera.disableView();
    		}
    	};
    
    	@Override
    	public void onCameraViewStarted(int width, int height) {
    		// TODO Auto-generated method stub
    		mRgba = new Mat(height, width, CvType.CV_8UC4);
    		mTmp = new Mat(height, width, CvType.CV_8UC4);
    		
    		mIntermediateMat = new Mat();
            mSize0 = new Size();
            mChannels = new MatOfInt[] { new MatOfInt(0), new MatOfInt(1), new MatOfInt(2) };
            mBuff = new float[mHistSizeNum];
            mHistSize = new MatOfInt(mHistSizeNum);
            mRanges = new MatOfFloat(0f, 256f);
            mMat0 = new Mat();
            mColorsRGB = new Scalar[] { new Scalar(200, 0, 0, 255), new Scalar(0, 200, 0, 255), new Scalar(0, 0, 200, 255) };
            mColorsHue = new Scalar[] {
                    new Scalar(255, 0, 0, 255), new Scalar(255, 60, 0, 255), new Scalar(255, 120, 0, 255), new Scalar(255, 180, 0, 255), new Scalar(255, 240, 0, 255),
                    new Scalar(215, 213, 0, 255), new Scalar(150, 255, 0, 255), new Scalar(85, 255, 0, 255), new Scalar(20, 255, 0, 255), new Scalar(0, 255, 30, 255),
                    new Scalar(0, 255, 85, 255), new Scalar(0, 255, 150, 255), new Scalar(0, 255, 215, 255), new Scalar(0, 234, 255, 255), new Scalar(0, 170, 255, 255),
                    new Scalar(0, 120, 255, 255), new Scalar(0, 60, 255, 255), new Scalar(0, 0, 255, 255), new Scalar(64, 0, 255, 255), new Scalar(120, 0, 255, 255),
                    new Scalar(180, 0, 255, 255), new Scalar(255, 0, 255, 255), new Scalar(255, 0, 215, 255), new Scalar(255, 0, 85, 255), new Scalar(255, 0, 0, 255)
            };
            mWhilte = Scalar.all(255);
            mP1 = new Point();
            mP2 = new Point();
    
            // Fill sepia kernel
            mSepiaKernel = new Mat(4, 4, CvType.CV_32F);
            mSepiaKernel.put(0, 0, /* R */0.189f, 0.769f, 0.393f, 0f);
            mSepiaKernel.put(1, 0, /* G */0.168f, 0.686f, 0.349f, 0f);
            mSepiaKernel.put(2, 0, /* B */0.131f, 0.534f, 0.272f, 0f);
            mSepiaKernel.put(3, 0, /* A */0.000f, 0.000f, 0.000f, 1f);
    	}
    	
    	@Override
    	public void onCameraViewStopped() {
    		// TODO Auto-generated method stub
    		mRgba.release();
    		mTmp.release();
    	}
    	
    	/**
    	 * 图像处理都写在此处
    	 */
    	@Override
    	public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    		mRgba = inputFrame.rgba();
    	    Size sizeRgba = mRgba.size();
    	    int rows = (int) sizeRgba.height;
    	    int cols = (int) sizeRgba.width;
    	    Mat rgbaInnerWindow;
    	        
    	    int left = cols / 8;
    	    int top = rows / 8;
    
    	    int width = cols * 3 / 4;
    	    int height = rows * 3 / 4;
    	    
    		switch (Cur_State) {
    		case 1:
    			//灰化处理
    			Imgproc.cvtColor(inputFrame.gray(), mRgba, Imgproc.COLOR_GRAY2RGBA,4);
    			break;
    		case 2:
    			//Canny边缘检测
    			mRgba = inputFrame.rgba();
    			Imgproc.Canny(inputFrame.gray(), mTmp, 80, 100);
    			Imgproc.cvtColor(mTmp, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
    			break;
    		case 3:
    			//Hist直方图计算
    			Mat hist = new Mat();
                int thikness = (int) (sizeRgba.width / (mHistSizeNum + 10) / 5);
                if(thikness > 5) thikness = 5;
                int offset = (int) ((sizeRgba.width - (5*mHistSizeNum + 4*10)*thikness)/2);
               
                // RGB
                for(int c=0; c<3; c++) {
                    Imgproc.calcHist(Arrays.asList(mRgba), mChannels[c], mMat0, hist, mHistSize, mRanges);
                    Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
                    hist.get(0, 0, mBuff);
                    for(int h=0; h<mHistSizeNum; h++) {
                        mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness;
                        mP1.y = sizeRgba.height-1;
                        mP2.y = mP1.y - 2 - (int)mBuff[h];
                        Imgproc.line(mRgba, mP1, mP2, mColorsRGB[c], thikness);
                    }
                }
                // Value and Hue
                Imgproc.cvtColor(mRgba, mTmp, Imgproc.COLOR_RGB2HSV_FULL);
                // Value
                Imgproc.calcHist(Arrays.asList(mTmp), mChannels[2], mMat0, hist, mHistSize, mRanges);
                Core.normalize(hist, hist, sizeRgba.height/2, 0, Core.NORM_INF);
                hist.get(0, 0, mBuff);
                for(int h=0; h<mHistSizeNum; h++) {
                    mP1.x = mP2.x = offset + (3 * (mHistSizeNum + 10) + h) * thikness;
                    mP1.y = sizeRgba.height-1;
                    mP2.y = mP1.y - 2 - (int)mBuff[h];
                    Imgproc.line(mRgba, mP1, mP2, mWhilte, thikness);
                }
    			break;
    		case 4:
    			//Sobel边缘检测
    			Mat gray = inputFrame.gray();
                Mat grayInnerWindow = gray.submat(top, top + height, left, left + width);
                rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
                Imgproc.Sobel(grayInnerWindow, mIntermediateMat, CvType.CV_8U, 1, 1);
                Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0);
                Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
                grayInnerWindow.release();
                rgbaInnerWindow.release();
    			break;
    		case 5:
    			//SEPIA(色调变换)
    			rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
                Core.transform(rgbaInnerWindow, rgbaInnerWindow, mSepiaKernel);
                rgbaInnerWindow.release();
    			break;
    		case 6:
    			//ZOOM放大镜
    			Mat zoomCorner = mRgba.submat(0, rows / 2 - rows / 10, 0, cols / 2 - cols / 10);
                Mat mZoomWindow = mRgba.submat(rows / 2 - 9 * rows / 100, rows / 2 + 9 * rows / 100, cols / 2 - 9 * cols / 100, cols / 2 + 9 * cols / 100);
                Imgproc.resize(mZoomWindow, zoomCorner, zoomCorner.size());
                Size wsize = mZoomWindow.size();
                Imgproc.rectangle(mZoomWindow, new Point(1, 1), new Point(wsize.width - 2, wsize.height - 2), new Scalar(255, 0, 0, 255), 2);
                zoomCorner.release();
                mZoomWindow.release();
    			break;
    		case 7:
    			//PIXELIZE像素化
    			rgbaInnerWindow = mRgba.submat(top, top + height, left, left + width);
                Imgproc.resize(rgbaInnerWindow, mIntermediateMat, mSize0, 0.1, 0.1, Imgproc.INTER_NEAREST);
                Imgproc.resize(mIntermediateMat, rgbaInnerWindow, rgbaInnerWindow.size(), 0., 0., Imgproc.INTER_NEAREST);
                rgbaInnerWindow.release();
    			break;
    		default:
    			//显示原图
    			mRgba = inputFrame.rgba();
    			break;
    		}
    		//返回处理后的结果数据
    		return mRgba;
    	}
    }
    


    2.效果图:

    Canny边缘检测:

            

    Hist直方图计算:

            

    Sobel边缘检测:

            

    SEPIA(色调变换):

            

    ZOOM放大镜:

            

    PIXELIZE像素化:
            

    展开全文
  • 今天在工作中要解决一个前端图像处理的需求。

    今天在工作中要解决一个前端图像处理的需求。在网上查找资料后,发现了glfx.js这样一个js图像处理库,它是一个基于WebGL的实时图像处理库。使用的方法如下:

    下载glfx

    glfx.js的源码下载下来,为了适应es6语法,在文件末尾最后加上一行代码

    export {fx};
    

    图像处理

    封装一个Vue图像处理组件,暂且叫做FrontProcess.vue。这个组件接收父组件待处理的图像url,当进行了图像处理操作后,携带处理后的图像url给父组件发送emit事件。父组件接收到事件后,更新图像url

    首先,我们导入glfx脚本

    import {fx} from '@/assets/js/glfx.js'
    

    定义data和props

    data(){
    	// 这里定义的是一些对象(保存canvas等数据)和参数值(如亮度/对比度等值)
        return {
            valueOfBrightness: 0,
            _canvas: null,
            _texture: null,
            imgElement: null,
            _draw: null,
            originalSrc: '',
            valueOfContrast: 0,
            isCurves: false,
            isDenoise: false,
            valueOfHue: 0,
            valueOfSaturation: 0,
            valueOfNoise: 0,
            valueOfSepia: 0,
            usmRadius: 0,
            usmStrength: 0,
            opBtn: []
        }
    },
    props: {
       imgUrl: {
           required: true
       }
    }
    

    将数据绑定到模板上

    <div class="front-process-container" v-loading="loading">
          <img id="original" crossorigin="anonymous" :src="imgUrl" ref="originalImg">
          <div class="slider-wrap">
              <label class="slider-label">亮度</label>
              <el-slider v-model="valueOfBrightness" :max="100" :min="-100" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">对比度</label>
              <el-slider v-model="valueOfContrast" :max="100" :min="-100" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">色调</label>
              <el-slider v-model="valueOfHue" :max="100" :min="-100" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">饱和度</label>
              <el-slider v-model="valueOfSaturation" :max="100" :min="-100" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">加噪</label>
              <el-slider v-model="valueOfNoise" :max="100" :min="0" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">深褐</label>
              <el-slider v-model="valueOfSepia" :max="100" :min="0" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">锐化半径</label>
              <el-slider v-model="usmRadius" :max="200" :min="0" @change="drawByParams"></el-slider>
          </div>
          <div class="slider-wrap">
              <label class="slider-label">锐化强度</label>
              <el-slider v-model="usmStrength" :max="5" :min="0" :step="0.01" @change="drawByParams"></el-slider>
          </div>
          <el-button class="op-btn" @click="drawByParams('curves')" :class="{active: isCurves}">反显</el-button>
          <el-button class="op-btn" @click="drawByParams('denoise')" :class="{active: isDenoise}">降噪</el-button>
          <el-button class="op-btn" @click="resetImg">恢复原图</el-button>
    </div>
    

    绑定方法

    // 初始化,根据glfx的说明按顺序调用,并将这些对象保存下来。
    getWebGLElements() {
        if (!this._canvas) {
            this._canvas = fx.canvas();
        }
    
        if (!this.imgElement) {
            this.imgElement = this.$refs.originalImg;
            this.originalSrc = this.imgElement.src;
        }
    
        if (!this._texture) {
            this._texture = this._canvas.texture(this.imgElement);
        }
    
        if (!this._draw) {
            this._draw = this._canvas.draw(this._texture)
        }
    }
    
    // 处理图像
    drawByParams(operation) {
        this.resetProperty()
        let opIndex = _.indexOf(this.opBtn, operation)
        if (opIndex !== -1) {
            this.opBtn.splice(opIndex, 1)
        } else {
            this.opBtn.push(operation)
        }
        this._draw.
            brightnessContrast(this.valueOfBrightness / 100, this.valueOfContrast / 100).
            hueSaturation(this.valueOfHue / 100, this.valueOfSaturation / 100).
            noise(this.valueOfNoise / 100).
            sepia(this.valueOfSepia / 100).
            unsharpMask(this.usmRadius, this.usmStrength);
        if (_.indexOf(this.opBtn, 'curves') !== -1) {
            this.isCurves = true
            this._draw.curves([[0,1], [1,0]], [[0,1], [1,0]], [[0,1], [1,0]])
        } else {
            this.isCurves = false
        }
        if (_.indexOf(this.opBtn, 'denoise') !== -1) {
            this.isDenoise = true
            this._draw.denoise(20)
        } else {
            this.isDenoise = false
        }
        this._draw.update()
        this.$emit('changeImg', this._canvas.toDataURL('image/png'))
    }
    

    图像处理效果图

    这是被随意拖拽设置的参数,然后调用glfx各个filter实现的效果。glfx还提供了很多图像处理的filter,我这里只用了其中一部分用来做演示。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tEpsmk9w-1571106060246)(http://wbjiang.cn/glfx%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E6%95%88%E6%9E%9C%E5%9B%BE.png?imageMogr2/auto-orient/blur/1x0/quality/75|watermark/2/text/d2JqaWFuZy5jbg==/font/5qW35L2T/fontsize/640/fill/IzQ5NzZEQg==/dissolve/90/gravity/SouthWest/dx/10/dy/10)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yemHc1E8-1571106060246)(http://wbjiang.cn/glfx%E6%95%88%E6%9E%9C%E5%9B%BE2.png?imageMogr2/auto-orient/blur/1x0/quality/75|watermark/2/text/d2JqaWFuZy5jbg==/font/5qW35L2T/fontsize/640/fill/IzQ5NzZEQg==/dissolve/90/gravity/SouthWest/dx/10/dy/10)]

    展开全文
  • 基于FPGA+DSP的实时图像处理平台的设计与实现[日期:2008-8-7]来源:电子技术应用 作者:鲁昌华,石洪源,梁银海,殷 俊[字体:大 中 小] 药品灌装生产前必须对药用玻璃瓶进行检测,把不合格品剔除,才能进行药品的...
  • 本文来自博客专栏《Python》本专栏专注于Python项目实战开发应用初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,...
  • 实时图像处理、高速数据运算处理要求其系统具有对数据处理速度快、数据吞吐率高以及多任务处理功能。目前大多数方案都是采用HPI数据传输方式,将ARM和DSP进行组合完成一些图像处理,DSP处理器只是完成图像采集、压缩...
  • 实时图像处理技术,尤其是基于多核DSP+FPGA架构的实时图像处理技术,因为该种方案本身所具有种种优点,又成为了现今各项图像处理新技术研究中的备受关注的焦点 红外图像 细胞图像 图像拼接 2.总体设计方案: FPGA...
  • OpenCV是著名的跨平台计算机...Opencv移植进Android平台可以在移动端实现图像处理,目标的识别等功能,具有良好的开发前景。 一.开发准备 第一步主要是搭好开发环境,将Opencv导入到Android Studio,可以直接在Andr
  • 本文着眼于图像处理系统的发展要求,说明了基于PCI总线的DSP图像处理系统的优点,并详细阐明了系统的硬件结构和PCI总线的驱动实现,最后介绍了系统实现的效果。  1 图像处理系统发展现状 在计算机信息处理及...
  • 1 引 言 随着计算机及通信技术的发展,图像和视频的应用愈加广泛。大部分图像数据在实际应用前皆需进行有针对性的处理,如根据图像...图像处理技术尤其是实时处理,现已成为一热门的研究课题。 实现图像处理的主要
  • OpenCV3基础——几种基本的图像处理

    万次阅读 多人点赞 2019-03-12 18:56:36
    虽然单单要做车牌号识别的话不需要特别多种类的图像处理,但是我们不能只是为了这么一个目标去学习,所以这次就讲一些OpenCV里基本的图像处理,大家以后可以根据需求使用不同的图像处理。 一、图像显示 这一步在...
  • 视频图像处理

    千次阅读 2018-07-24 13:27:39
    众所周知的CNN网络对于图像的空间域的处理具有很好的效果,在单张图像的分类分割目标检测等问题上表现出了很好的效果。很多人或许有和我之前一样的疑问,既然单张图像上做的效果已经达到state-of-art的效果,为什么...
  • 通过NI Vision Assistant 实现Labview实时图像处理的步骤 可分为两步:相机实时图像获取,图像处理。 第一步 相机实时图像获取:Labview中有很多范例:帮助-查找范例-目录结构-Vision Acquisition-NI-IMAQdx,随便...
  • stm32f1+ov7725进行图像处理

    万次阅读 多人点赞 2019-04-24 20:32:31
    最近学了一点stm32做图像处理的皮毛. 做了个小玩意儿,用了stm32做了灰度化,二值化,从而找到一条路线的中点,然后根据偏差对输出相应的pwm。 适合初学者看看,很浅层。f1带图像有点吃力,所以分别把图像和控制...
  • 使用Andorid手机图像识别的项目,需要在屏幕上实时显示图像处理后的效果。需要具备以下几个特点: 1、使用Android手机摄像头;...2、能够进行实时图像识别、图像处理; 3、最终手机屏幕上只实时显示处理后的效果。
  • 图像处理OpenCV算法01

    千次阅读 2018-06-25 10:10:43
     2、图像由数组构成,黑白图像就是一个单通道的二维矩阵,如同一个的棋盘(矩阵),棋盘中每个点的数字大小代表着图像像素灰度的高低,通过像素的差异形成素描般的黑白图像;而彩色图像则是由三个通道组合而成的一...
  • 如何通过相机实时显示处理图像
  • MATLAB--数字图像处理 简单人脸识别

    千次阅读 2020-05-23 10:25:58
    找到图像中连通域面积最大的那块连通域。 i=imread('face.jpg'); I=rgb2gray(i); BW=im2bw(I); %利用阈值值变换法将灰度图像转换成二进制图像 figure(1); imshow(BW); %最小化背景 [n1 n2]=size(BW); r=floor(n1...
  • python 使用OpenCV库实现图像处理

    千次阅读 2019-01-03 13:28:01
    OpenCV是一个C++库,目前流行的计算机视觉编程库,用于实时处理计算机视觉方面的问题,它涵盖了很多计算机视觉领域的模块 一:OpenCV安装 pip install opencv-python 如果安装失败的话,直接下载whl安装包进行...
1 2 3 4 5 ... 20
收藏数 97,671
精华内容 39,068
关键字:

实时图像处理