2019-04-26 23:50:29 zaishuiyifangxym 阅读数 569

目录

1 什么是阈值化- threshold()

2 二进制阈值化

3 反二进制阈值化

4 截断阈值化

5 反阈值化为0

6 阈值化为0

7 小结

参考资料


1 什么是阈值化- threshold()

图像的二值化或阈值化 (Binarization) 旨在提取图像中的目标物体,将背景以及噪声区分开来。通常会设定一个阈值 T,通过阈值 T 将图像的像素划分为两类:大于阈值 {\color{Red} T} 的像素群和小于阈值 {\color{Red} T} 的像素群。

灰度转换处理后的图像中,每个像素都只有一个灰度值,其大小表示明暗程度。二值化处理可以将图像中的像素划分为两类颜色,常用的二值化算法如下所示:

                                                                            \left\{ {\begin{array}{*{20}{c}} {Y = 0}&, \\ {Y = 255}&, \end{array}\begin{array}{*{20}{c}} {gray < T} \\ {gray > = T} \end{array}} \right.

其中,当灰度Gray小于阈值T时,其像素设置为0,表示黑色;

           当灰度Gray大于或等于阈值T时,其Y值为255,表示白色。

Python OpenCV中提供了阈值函数 threshold() 实现二值化处理,其函数形式及参数如下图所示:

retval, dst = cv2.threshold(src, thresh, maxval, type)

其中,参数:

retval:阈值        

dst: 处理结果

src,:原图像

thresh:阈值

maxval:最大值

type:类

 

常用的方法如下表所示,其中函数中的参数Gray表示灰度图,参数127表示对像素值进行分类的阈值,参数255表示像素值高于阈值时应该被赋予的新像素值,最后一个参数对应不同的阈值处理方法。

 

对应OpenCV提供的五张图如下所示,第一张为原图,后面依次为:

二进制阈值化反二进制阈值化截断阈值化反阈值化为0 和 阈值化为0

 

二值化处理广泛应用于各行各业,比如生物学中的细胞图分割、交通领域的车牌设别等。在文化应用领域中,通过二值化处理将所需民族文物图像转换为黑白两色图,从而为后面的图像识别提供更好的支撑作用。下图表示图像经过各种二值化处理算法后的结果,其中“BINARY”是最常见的黑白两色处理。下面将依次对5种阈值化处理方法进行介绍以及实验对比。


 

2 二进制阈值化

二进制阈值化方法先要选定一个特定的阈值量,比如127。新的阈值产生规则如下:

                                                             dst(x,y) = \left\{ {\begin{array}{*{20}{c}} {\max Val}&,\\ 0&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于等于127的像素点的灰度值设定为最大值(如8位灰度值最大为255);

(2) 灰度值小于127的像素点的灰度值设定为0 ;

例如,163->255,86->0,102->0,201->255

使用关键字为:cv2.THRESH_BINARY

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#二进制阈值化处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:(R, B两个通道均使用了阈值处理


 

3 反二进制阈值化

反二进制阈值化方法与二进制阈值化方法相似,先要选定一个特定的灰度值作为阈值,比如127。新的阈值产生规则如下公式所示:

                                                           dst(x,y) = \left\{ {\begin{array}{*{20}{c}} 0&,\\ {\max Val}&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于127的像素点的灰度值设定为0(以8位灰度图为例);

(2) 小于该阈值的灰度值设定为255;

例如,163->0,86->255,102->255,201->0。

使用关键字为: cv2.THRESH_BINARY_INV

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY_INV)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#反二进制阈值化处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY_INV)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:


 

4 截断阈值化

截断阈值化方法需要选定一个阈值,图像中大于该阈值的像素点被设定为该阈值,小于该阈值的保持不变,比如127。新的阈值产生规则如下:

                                                          dst(x,y) = \left\{ {\begin{array}{*{20}{c}} {threshold}&,\\ {src(x,y)}&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于等于127的像素点的灰度值设定为该阈值127;

(2) 小于该阈值的灰度值不改变;

例如,163->127,86->86,102->102,201->127。

使用关键字为: cv2.THRESH_TRUNC

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TRUNC)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#截断阈值化处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TRUNC)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:[ 该处理方法相当于把图像中比较亮(大于127,偏向于白色)的像素值处理为阈值。]


 

5 反阈值化为0

反阈值化为0 方法先选定一个阈值,比如127,接着对图像的灰度值进行如下处理:

                                                           dst(x,y) = \left\{ {\begin{array}{*{20}{c}} 0&,\\ {src(x,y)}&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于等于阈值127的像素点变为0 ;

(2) 小于该阈值的像素点值保持不变;

例如,163->0,86->86,102->102,201->0。

使用关键字为: cv2.THRESH_TOZERO_INV 

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO_INV)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#反阈值化为0处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO_INV)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:


 

6 阈值化为0

阈值化为0 方法先选定一个阈值,比如127,接着对图像的灰度值进行如下处理:

                                                         dst(x,y) = \left\{ {\begin{array}{*{20}{c}} {src(x,y)}&,\\ 0&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

 

(1) 大于等于阈值127的像素点,值保持不变;

(2) 小于该阈值的像素点值设置为0 ;

例如,163->163,86->0,102->0,201->201。

使用关键字为: cv2.THRESH_TOZERO

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#阈值化为0处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:(该方法把比较亮的部分不变,比较暗的部分处理为0。)


 

7 小结

把上面提及的五种阈值处理方法(二进制阈值化反二进制阈值化截断阈值化反阈值化为0 和 阈值化为0)放在一起进行对比

代码如下所示:(注意一个窗口多张图像的用法

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#阈值化处理
ret,thresh1=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY)
ret,thresh2=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3=cv2.threshold(GrayImage,127,255,cv2.THRESH_TRUNC)
ret,thresh4=cv2.threshold(GrayImage,127,255,cv2.THRESH_TOZERO)
ret,thresh5=cv2.threshold(GrayImage,127,255,cv2.THRESH_TOZERO_INV)

#显示结果
titles = ['Gray Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [GrayImage, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
   plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

 

运行结果如下所示:(注意一个窗口多张图像的用法


 

参考资料

[1] https://blog.csdn.net/Eastmount/article/details/83548652

[2] Python+OpenCV图像处理

2018-01-24 18:57:06 baidu_33939056 阅读数 5714

1,binary dilation,用来去除一些灰度值小的噪声。在具体应用中如何选取核需要尝试
scipy 中有现成的包可以调用 链接

2,Otsu’s method,用来对图像进行二值化,可以用来区分前景和背景。利用opencv 代码如下:

cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)

3,flood fill algorithm:文档,l实例程序

2017-04-01 13:46:29 hqxdamowang 阅读数 2235

图像的边缘检测:

边缘检测技术对于处理数字图像非常重要,因为边缘是所要提取目标和背景的分界线,提取出边缘才能将目标和背景区分开来。在图像中,边界表明一个特征区域的终结和另一个特征区域的开始,边界所分开区域的内部特征或属性是一致的,而不同的区域内部的特征或属性是不同的,边缘检测正是利用物体和背景在某种图像特性上的差异来实现的,这些差异包括灰度,颜色或者纹理特征。边缘检测实际上就是检测图像特征发生变化的位置。

边缘检测基本思想是先检测图像中的边缘点,再按照某种策略将边缘点连接成轮廓,从而构成分割区域。由于边缘是所要提取目标和背景的分界线,提取出边缘才能将目标和背景区分开,因此边缘检测对于数字图像处理十分重要。

边缘大致可以分为两种:(一)阶跃状边缘:边缘两边像素的灰度值明显不同。

                                            (二)屋顶状边缘:边缘处于灰度值有小到大再到小变化的转折点处。

一阶微分算子检测图片边缘:一阶微分算子一般借助空域微分算子通过卷集完成,但实际上数字图像中求导是利用差分近似微分来进行的。        梯度对应一阶导数,梯度算子是一阶导数算子。对一个连续函数f(x,y),它在位置(x,y)梯度可表示为一个矢量。对于数字图像,导数可以用差分来近似,在实际中常用小区域模板卷积来近似计算。对Gx和Gy各用一个模板,所以需要两个模板组合起来构成一个梯度算子。根据模板的大小,其中元素(系数)值的不同,可以提出很多的模板,构成许多的检测算子。

二阶微分算子检测图片边缘:Laplacian算子:这是二阶微分算子。其具有各向同性,即与坐标轴方向无关,坐标轴旋转后梯度结果不变。但是,其对噪声比较敏感,所以,图像一般先经过平滑处理,因为平滑处理也是用模板进行的,所以,通常的分割算法都是把Laplacian算子和平滑算子结合起来生成一个新的模板。 Laplacian算子一般不以其原始形式用于边缘检测,因为其作为一个二阶导数,Laplacian算子对噪声具有无法接受的敏感性;同时其幅值产生算边缘,这是复杂的分割不希望有的结果;最后Laplacian算子不能检测边缘的方向;所以Laplacian在分割中所起的作用包括:(1)利用它的零交叉性质进行边缘定位;(2)确定一个像素是在一条边缘暗的一面还是亮的一面;一般使用的是高斯型拉普拉斯算子(Laplacian of a Gaussian,LoG),由于二阶导数是线性运算,利用LoG卷积一幅图像与首先使用高斯型平滑函数卷积改图像,然后计算所得结果的拉普拉斯是一样的。所以在LoG公式中使用高斯函数的目的就是对图像进行平滑处理,使用Laplacian算子的目的是提供一幅用零交叉确定边缘位置的图像;图像的平滑处理减少了噪声的影响并且它的主要作用还是抵消由Laplacian算子的二阶导数引起的逐渐增加的噪声影响。

Canny算子:Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- 算法能够尽可能多地标识出图像中的实际边缘。 好的定位- 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。 最小响应- 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。 为了满足这些要求 Canny 使用了变分法,这是一种寻找满足特定功能的函数的方法。最优检测使用四个指数函数项的和表示,但是它非常近似于高斯函数的一阶导数。


什么是角点:角点就是极值点,即在某方面属性特别突出的点。当然,你可以自己定义角点的属性(设置特定熵值进行角点检测)。角点可以是两条线的交叉处,也可以是位于相邻的两个主要方向不同的事物上的点。


角点特征检测:目前的角点检测算法可归纳为3类:基于灰度图像的角点检测、基于二值图像的角点检测、基于轮廓曲线的角点检测。角点是图像很重要的特征,对图像图形的理解和分析有很重要的作用。对灰度图像、二值图像、边缘轮廓曲线的角点检测算法进行综述,分析了相关的算法,并对各种检测算法给出了评价。

Harris角点:人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。如果在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么就认为在窗口内遇到了角点。如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度没有发生变化,那么窗口内就不存在角点;如果窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一些方向上没有发生变化,那么,窗口内的图像可能就是一条直线的线段。

1.准确性:即使很细小的角点,算法也能检测到;

2.定位性:检测到的角点应尽可能地接近它们在图像中的真实位置;

3稳定性:对相同场景拍摄的多幅图片,每一个角点的位置都不应该移动;

4.实时性:角点检测算法的计算量越小、运行的速度越快越好;

5.鲁棒性:对噪声具有抗干燥性。


surf特征提取:计算机视觉中,引入尺度不变的特征,主要的思想是每个检测到的特征点都伴随着对应的尺寸因子。当我们想匹配不同图像时,经常会遇到图像尺度不同的问题,不同图像中特征点的距离变得不同,物体变成不同的尺寸,如果我们通过修正特征点的大小,就会造成强度不匹配。为了解决这个问题,提出一个尺度不变的SURF特征检测,在计算特征点的时候把尺度因素加入之中。SURF与SIFT算法相似,SIFT算法比较稳定,检测特征点更多,但是复杂度较高,而SURF要运算简单,效率高,运算时间短一点。

第一、SURF算法是对SIFT算法加强版,同时加速的具有鲁棒性的特征。第二、标准的SURF算子比SIFT算子快好几倍,并且在多幅图片下具有更好的鲁棒性。SURF最大的特征在于采用了harr特征以及积分图像integral image的概念,这大大加快了程序的运行时间。


2018-01-04 20:20:28 coming_is_winter 阅读数 571

     图像处理之前景检测(一)之单高斯模型

    

     运动前景对象检测一直是国内外视觉监控领域研究的难点和热点之一,其目的是从序列图像中将变化区域从背景图像中提取出来,运动前景对象的有效检测对于对象跟踪、目标分类、行为理解等后期处理至关重要,那么区分前景对象,非常关键的一个问题是确定一个非常合适的背景,背景从象素的角度来理解,每一个象素就是有可能是前景点,也有可能是背景点,那么我们就要防止背景中误进入原属于前景点的对象,目前有几种常用的方法,但分别有利弊。

     具体类型见(参考及推荐文献):

     ☆Ronny丶   目标检测中背景建模方法

    smallroof    前景目标检测1(总结)

    这里按照顺序,将感兴趣的有关算法进行梳理。首先是单高斯模型。

      单高斯模型建模比较简单,利用没有运动目标的图像将整个窗口进行高斯建模,对比后续对应点上的像素数据,符合高斯模型,持续为背景,超出某个阈值,则认为为前景。

      具体原理参考:

      沈春旭    运动目标检测_单高斯背景建模

     这里主要将  zhengtu009  的  单高斯背景建模原理及代码实现  中的C接口代码进行升级为C++接口。环境为VS2015+opencv3.2 contrib版。

        

#include<iostream>
#include<opencv.hpp>
using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
	//新建窗口
	namedWindow("origin", WINDOW_AUTOSIZE);
	namedWindow("background", WINDOW_AUTOSIZE);
	namedWindow("foreground", WINDOW_AUTOSIZE);


	double alpha = 0.05;    //背景建模alpha值
	double std_init = 20;    //初始标准差
	double var_init = std_init * std_init;    //初始方差    
	double lamda = 2.5 * 1.2;    //背景更新参数

								 //视频文件
	VideoCapture capture("E://素材//3.mp4");
	

	Mat frame;        //原始图像

	Scalar pixel = { 0 };        //像素原始值
	Scalar pixel_u = { 0 };        //像素期望
	Scalar pixel_d = { 0 };        //像素前景
	Scalar pixel_var = { 0 };    //像素方差
	Scalar pixel_std = { 0 };    //像素标准差

	capture >> frame;
	Mat frame_u(frame.rows,frame.cols,  CV_8UC3);
	Mat frame_d(frame.rows,frame.cols , CV_8UC3);
	Mat frame_var(frame.rows,frame.cols,  CV_8UC3);
	Mat frame_std(frame.rows,frame.cols,  CV_8UC3);

	for (int y = 0; y < frame.rows; ++y)
	{
		for (int x = 0; x < frame.cols; ++x)
		{
			pixel =frame.at<Vec3b>(y,x);
			pixel_u.val[0] = pixel.val[0];
			pixel_u.val[1] = pixel.val[1];
			pixel_u.val[2] = pixel.val[2];

			pixel_d.val[0] = 0;
			pixel_d.val[1] = 0;
			pixel_d.val[2] = 0;

			pixel_std.val[0] = std_init;
			pixel_std.val[1] = std_init;
			pixel_std.val[2] = std_init;

			pixel_var.val[0] = var_init;
			pixel_var.val[1] = var_init;
			pixel_var.val[2] = var_init;
			
			//cvSet2D(frame_u, y, x, pixel_u);
			frame_u.at<Vec3b>(y, x)[0] = pixel_u[0];
			frame_u.at<Vec3b>(y, x)[1] = pixel_u[1];
			frame_u.at<Vec3b>(y, x)[2] = pixel_u[2];
			frame_d.at<Vec3b>(y, x)[0] = pixel_d[0];
			frame_d.at<Vec3b>(y, x)[1] = pixel_d[1];
			frame_d.at<Vec3b>(y, x)[2] = pixel_d[2];
			frame_var.at<Vec3b>(y, x)[0] = pixel_var[0];
			frame_var.at<Vec3b>(y, x)[1] = pixel_var[1];
			frame_var.at<Vec3b>(y, x)[2] = pixel_var[2];
			frame_std.at<Vec3b>(y, x)[0] = pixel_std[0];
			frame_std.at<Vec3b>(y, x)[1] = pixel_std[1];
			frame_std.at<Vec3b>(y, x)[2] = pixel_std[2];
		}
	}
	while (1)        //按ESC键退出, 帧率33ms
	{
		capture>>frame ;
		//视频结束退出
		if (frame.empty()==1)
		{
			break;
		}
		//单高斯背景更新
		for (int y = 0; y < frame.rows; ++y)
		{
			for (int x = 0; x < frame.cols; ++x)
			{
				
				pixel = frame.at<Vec3b>(y, x);
				
				pixel_u = frame_u.at<Vec3b>(y, x);
				
				pixel_d = frame_d.at<Vec3b>(y, x);
				
				pixel_std = frame_std.at<Vec3b>(y, x);
				
				pixel_var = frame_var.at<Vec3b>(y, x);

				//|I-u| < lamda*std 时认为是背景, 进行更新
				if (fabs(pixel.val[0] - pixel_u.val[0]) < lamda * pixel_std.val[0] &&
					fabs(pixel.val[1] - pixel_u.val[1]) < lamda * pixel_std.val[1] &&
					fabs(pixel.val[2] - pixel_u.val[2]) < lamda * pixel_std.val[2])
				{
					//更新期望 u = (1-alpha)*u + alpha*I
					pixel_u.val[0] = (1 - alpha) * pixel_u.val[0] + alpha * pixel.val[0];
					pixel_u.val[1] = (1 - alpha) * pixel_u.val[1] + alpha * pixel.val[1];
					pixel_u.val[2] = (1 - alpha) * pixel_u.val[2] + alpha * pixel.val[2];


					//更新方差 var = (1-alpha)*var + alpha*(I-u)^2
					pixel_var.val[0] = (1 - alpha) * pixel_var.val[0] +
						(pixel.val[0] - pixel_u.val[0]) * (pixel.val[0] - pixel_u.val[0]);
					pixel_var.val[1] = (1 - alpha) * pixel_var.val[1] +
						(pixel.val[1] - pixel_u.val[1]) * (pixel.val[1] - pixel_u.val[1]);
					pixel_var.val[2] = (1 - alpha) * pixel_var.val[2] +
						(pixel.val[2] - pixel_u.val[2]) * (pixel.val[2] - pixel_u.val[2]);

					//更新标准差
					pixel_std.val[0] = sqrt(pixel_var.val[0]);
					pixel_std.val[1] = sqrt(pixel_var.val[1]);
					pixel_std.val[2] = sqrt(pixel_var.val[2]);

					//写入矩阵
					//cvSet2D(frame_u, y, x, pixel_u);
					frame_u.at<Vec3b>(y, x)[0] = pixel_u[0];
					frame_u.at<Vec3b>(y, x)[1] = pixel_u[1];
					frame_u.at<Vec3b>(y, x)[2] = pixel_u[2];
					//cvSet2D(frame_var, y, x, pixel_var);
					//cvSet2D(frame_std, y, x, pixel_std);
					frame_var.at<Vec3b>(y, x)[0] = pixel_var[0];
					frame_var.at<Vec3b>(y, x)[1] = pixel_var[1];
					frame_var.at<Vec3b>(y, x)[2] = pixel_var[2];
					frame_std.at<Vec3b>(y, x)[0] = pixel_std[0];
					frame_std.at<Vec3b>(y, x)[1] = pixel_std[1];
					frame_std.at<Vec3b>(y, x)[2] = pixel_std[2];
				}
				else
				{
					pixel_d.val[0] = pixel.val[0] - pixel_u.val[0];
					pixel_d.val[1] = pixel.val[1] - pixel_u.val[1];
					pixel_d.val[2] = pixel.val[2] - pixel_u.val[2];
					//cvSet2D(frame_d, y, x, pixel_d);
					frame_d.at<Vec3b>(y, x)[0] = pixel_d[0];
					frame_d.at<Vec3b>(y, x)[1] = pixel_d[1];
					frame_d.at<Vec3b>(y, x)[2] = pixel_d[2];
				}
			}
		}
     	imshow("origin", frame);
		imshow("background", frame_u);		
		imshow("foreground", frame_d);
		waitKey(20);
	}

	return 0;
}
      代码只是对于函数进行升级,但实现结果较老版些许不同,不知是版本更新问题,还是升级代码存在未知错误,大家辩证看待。

     

    原代码结果:

   

    

    升级代码结果:



    

     结束。

     

     视频素材下载地址:行人检测

没有更多推荐了,返回首页