2.OpenCV图像处理技术

OpenCV-帧差法

Q1:Qt中图像的显示方式

A1:

QT窗口绘图,重写绘图事件QPaintEvent

QLabel转换为QImage

QPixmap *pixmap = new QPixmap(imgpath);//加载图片
QLabel *labelname = new QLabel();//初始化控件
pixmap->scaled(labelname->size(), Qt::KeepAspectRatio);//设置图片大小
labelname->setScaledContents(true);//设置图片自适应控件大小
labelname->setPixmap(*pixmap);//把图片放到label中

Q2:图像与视频的关系

A2:视频的本质即图像
图像:人对视觉感知的物质再现。
二维图像:纹理、亮度信息
三维图像:纹理、亮度、深度信息
视频:多幅连续的图像,包含图像的运动信息。 由于人眼识别的频率(一般为**25frame/s**)有限,故而在单位时间内看到的图像数目超过一定的数目,给人眼造成的错觉就是画面是动态的。

Q3:开运算与闭运算的应用时机

开运算:先对图像腐蚀后膨胀
作用:用来消除小的物体,平滑形状边界,并且不改变其面积。可以去除小颗粒噪声,断开物体之间的粘连。
在这里插入图片描述总结:
(1)开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便。
(2)开运算是一个基于几何运算的滤波器。
(3)结构元素大小的不同将导致滤波效果的不同。
(4)不同的结构元素的选择导致了不同的分割,即提取出不同的特征。
在粘连目标的分离机背景噪声(椒盐噪声)的取出方面有较好的效果。

闭运算:先对图像膨胀后腐蚀
作用:用来填充物体内的小空洞,连接邻近的物体,连接断开的轮廓线,平滑其边界的同时不改变面积。在这里插入图片描述总结:
(1)闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
(2)闭运算是通过填充图像的凹角来滤波图像的。
(3)结构元素大小的不同将导致滤波效果的不同。
(4)不同结构元素的选择导致了不同的分割。
在去除图像前景噪声方面有较好的应用。

一、帧差法

(一)概念简介

1. 专业理解
  一种通过对视频图像序列中相邻两帧作差分运算来获得运动目标轮廓的方法。可以很好地适用于存在多个运动目标摄像机移动的情况。亦即当监控场景中出现异常物体运动时,帧与帧之间会出现比较明显的差别,两帧相减,得到两帧图像亮度差的绝对值,判断它是否大于阈值来分析视频会图像序列的运动特性,确定图像序列中有无物体运动。图像序列逐帧的差分,相当于对图像序列进行了时域下的高通滤波

2. 简单理解:翻页动画

火柴人翻页动画

(二)操作步骤——检测车辆运动

1. 灰度处理

//CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
//灰度处理
cvtColor(frontFrame, frontGray, CV_BGR2GRAY);
cvtColor(postFrame, postGray, CV_BGR2GRAY);

测试Demo

Mat src = imread("demo.jpg");
imshow("src", src);
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
imshow("gray",gray);
waitKey(0);

在这里插入图片描述在这里插入图片描述

2. 帧差处理

目的:对比两帧图像之间的差异,捕获运动物体。
缺点:所有运动物体均被捕获。

//CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst);
Mat diff;
absdiff(frontGray, postGray, diff);

在这里插入图片描述

3. 二值化

函数原型:CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
double thresh, double maxval, int type );
参数说明
src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者有区别)
dst:输出图像
thresh:阈值
maxval:dst图像中最大值
type:阈值类型

阈值类型

//二值化处理
threshold(diff, diff, 25, 255, CV_THRESH_BINARY);

在这里插入图片描述

4. 腐蚀

简介:腐蚀可以理解为B的中心(锚点)沿着A的内边界走了一圈。腐蚀也是对高亮部分而言,A区域之外的部分 < A的高亮像素,所里里面被外面取代。

在这里插入图片描述

目的:降噪。尽可能去除视频中的白色噪点

//创建结构元素
//CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
Mat structureElenent = cv::getStructuringElement(MORPH_RECT,Size(3,3));
//腐蚀操作
//CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,
                         Point anchor = Point(-1,-1), int iterations = 1,
                         int borderType = BORDER_CONSTANT,
                         const Scalar& borderValue = morphologyDefaultBorderValue() );
cv::erode(diff,diff,structureElenent);

在这里插入图片描述

5. 膨胀

简介:膨胀是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长。

在这里插入图片描述

目的:将主要物体的白色变“胖”。

//创建结构元素
Mat structureElenent2 = cv::getStructuringElement(MORPH_RECT,Size(20,20));
//膨胀处理
//CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel,
                          Point anchor = Point(-1,-1), int iterations = 1,
                          int borderType = BORDER_CONSTANT,
                          const Scalar& borderValue = morphologyDefaultBorderValue() );
dilate(diff, diff, structureElenent2);

在这里插入图片描述

6. 标记动态物体(保存关键点)

//动态物体位置坐标标记:从左上角开始标记
vector<vector<Point>>contours;
//CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              int mode, int method, Point offset = Point());
findContours(diff, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

7. 提取关键点

//提取关键点  
vector<vector<Point>>contours_poly(contours.size());//同样大小
vector<Rect>boundRect(contours.size());

8. 边框绘制

//边框绘制
int x, y, w, h;
int num = contours.size();
for(int i=0; i<num; i++)
{
    
    
	 //CV_EXPORTS_W void approxPolyDP( InputArray curve,
                                OutputArray approxCurve,
                                double epsilon, bool closed );
   approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
   //V_EXPORTS_W Rect boundingRect( InputArray points );
   boundRect[i] = boundingRect(Mat(contours_poly[i]));
   x=boundRect[i].x;
   y=boundRect[i].y;
   w=boundRect[i].width;
   h=boundRect[i].height;

   //绘制矩形
   //CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);
   rectangle(resFrame, Point(x, y), Point(x + w, y + h), Scalar(0, 255, 0), 2);
   //调整视频显示大小
   namedWindow("resFrame", 0);
   resizeWindow("resFrame", resFrame.cols/2, resFrame.rows/2);
   imshow("resFrame", resFrame);
}

在这里插入图片描述

联合展示:原视频->帧差法处理->二值化->腐蚀->膨胀->关键点提取及边框绘制
在这里插入图片描述

(三)完整代码

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

Mat MoveCheck(Mat &frontFrame, Mat &postFrame)
{
    
    
    Mat resFrame = frontFrame.clone();
    Mat frontGray, postGray;
    //灰度处理
    cvtColor(resFrame, frontGray, CV_BGR2GRAY);
    cvtColor(postFrame, postGray, CV_BGR2GRAY);


    //帧差法处理:对比两帧图像之间的差异,捕获运动物体
    //缺点:所有运动物体都会显示
    Mat diff;
    absdiff(frontGray, postGray, diff);
    namedWindow("absdiff", 0);
    resizeWindow("absdiff", diff.cols/4, diff.rows/4);
    imshow("absdiff", diff);

    //二值化处理
    threshold(diff, diff, 25, 255, CV_THRESH_BINARY);
    namedWindow("threshold", 0);
    resizeWindow("threshold", diff.cols/4, diff.rows/4);
    imshow("threshold", diff);

    //开运算:先腐蚀再膨胀->去除主要高亮物体背景中白色噪点凸显高亮物体
    //闭运算:先膨胀再腐蚀->去除主要高亮物体内部小型黑洞凸显高亮物体

    //腐蚀处理:降噪:尽可能去除视频中的白色噪点
    //创建结构元素
    Mat structureElenent = cv::getStructuringElement(MORPH_RECT,Size(3,3));
    //腐蚀操作
    cv::erode(diff,diff,structureElenent);
    namedWindow("erode", 0);
    resizeWindow("erode", diff.cols/4, diff.rows/4);
    imshow("erode", diff);

    //膨胀处理:将主要物体的白色变“胖”
    Mat structureElenent2 = cv::getStructuringElement(MORPH_RECT,Size(20,20));
    dilate(diff, diff, structureElenent2);
    namedWindow("dilate", 0);
    resizeWindow("dilate", diff.cols/4, diff.rows/4);
    imshow("dilate", diff);


    //动态物体位置坐标标记:从左上角开始标记
    vector<vector<Point>>contours;
    findContours(diff, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    //提取关键点
    vector<vector<Point>>contours_poly(contours.size());//同样大小
    vector<Rect>boundRect(contours.size());

    //边框绘制
    int x, y, w, h;
    int num = contours.size();
    for(int i=0; i<num; i++)
    {
    
    
        approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
        boundRect[i] = boundingRect(Mat(contours_poly[i]));
        x=boundRect[i].x;
        y=boundRect[i].y;
        w=boundRect[i].width;
        h=boundRect[i].height;

        //绘制矩形
        rectangle(resFrame, Point(x, y), Point(x + w, y + h), Scalar(0, 255, 0), 2);
        namedWindow("resFrame", 0);
        resizeWindow("resFrame", resFrame.cols/4, resFrame.rows/4);
        imshow("resFrame", resFrame);
    }


    return resFrame;
}
int main()
{
    
    
    Mat frame;
    Mat temp;
    Mat res;
    int count = 0;
    VideoCapture cap("StrangerThings.mp4");
    while(cap.read(frame))
    {
    
    
        count++;
        if(count == 1)
        {
    
    
            res = MoveCheck(frame, frame);
        }
        else
        {
    
    
            res = MoveCheck(temp, frame);
        }
        temp = frame.clone();
        namedWindow("frame", 0);
        resizeWindow("frame", frame.cols/4, frame.rows/4);
        imshow("frame", frame);
        waitKey(30);
    }

    return 0;
}

二、阈值分割(二值化)

三、像素模式

简介:计算机世界里亮度各异的点,用矩阵表示,矩阵里面元素的值作为像素的亮度,可被表示为多种模式,如:位图模式、灰度模式、RGB模式。其中,每个像素有三个通道。

像素(Pixel):构成图片的小色点。
分辨率(单位DPI):每英寸(Inch)上的像素数量,可以看做是这些小色点的分布密度。
像素相同时,分辨率越高则像素密度越大,实际打印尺寸越小,图像也越细腻。

实际尺寸(英寸)=像素/分辨率;1英寸=2.54厘米

例:一张图片宽为600像素,分辨率为300,
则实际打印宽度为:600/300=2英寸,约为5厘米。

位图模式

用点阵来表示黑白图像,印刷中常用。1位深度(二进制0/1)

灰度模式

  由0(纯黑)-255(纯白)256种颜色组成的黑白图像,所以模式的图像均可转换为灰度模式。8位[1个字节]深度(2^8)——单通道

RGB模式

  由色光三原色红、绿、蓝组成的图像(加光混合),适用于数码显像。3个通道,每个通道8位深度。24位深度(2^24) 1677万种颜色[真彩色]——3通道

:当需要将彩色模式转换为位图模式时,必须先转换为灰度模式,由灰度模式才能转换为位图模式。 如果选择了灰度模式,则图像中没有颜色信息,色彩饱和度为零,图像有256个灰度级别,从亮度0(黑)到255(白)。如果要编辑处理黑白图像,或将彩色图像转换为黑白图像,可以指定图像的模式为灰度,由于灰度图像的色彩信息都从文件中去掉了,所以灰度相对彩色来讲文件大小要小得多。

四、噪点

  图像噪声(image noise)是图像中一种亮度或颜色信息的随机变化(被拍摄物体本身并没有),通常是电子噪声的表现。它一般是由扫描仪或数码相机的传感器和电路产生的,也可能是受胶片颗粒或者理想光电探测器中不可避免的的散粒噪声影响产生的。图像噪声是图像拍摄过程中不希望存在的副产品,给图像带来了错误和额外的信息。

五、卷积神经网络

卷积神经网络超详细介绍

猜你喜欢

转载自blog.csdn.net/weixin_46134582/article/details/123996941
今日推荐