opencv第九章-图像局部与分割

来源:互联网 发布:怎么申请淘宝介入退款 编辑:程序博客网 时间:2024/06/06 22:59

opencv-图像局部与分割

第一、局部与分割

本章重点讲述如何从图像中将目标或部分目标分割出来。这样做的原因很明显,比如在视频安全应用中,摄像机经常观测一个不变的背景,而实际上我们对这些背景并不感兴趣。我们所感兴趣的只是当行人或车辆进入场景时或者当某些东西被遗留在场景中时。我们希望分离出这些事件而忽略没有任何事件发生的时间段。


我们可以把图像预处理成有意义的超像素所组成的诸如包含类似四肢、头发、脸、躯干、树叶、湖泊、道路、草坪等物体的图像区域。这些超像素的使用节省了计算量。比如,对一幅图像做目标分类器处理的时候,我们只需要在包含每个超像素的一个区域进行搜索。这样可能只需要跟踪这些大的区域,而不是区域中的每一个像素点。


第二、背景减除

由于背景减除简单而去摄像机在很多情况下是固定的,在视频安全应用领域,背景减除(又名背景差分)也许是最基本的图像处理操作。要实现背景减除,我们必须首先“学习”背景模型。


一旦背景模型建立,将背景模型和当前的图像进行比较,然后减去这些已知的背景信息,则剩下的目标物大致就是所求的前进目标了。


当然,“背景”在不同的应用场合下是一个很难定义的问题。通常情况下,背景被认为是在任何所感兴趣的时期内,场景中保持静止或周期运动的目标。整个场景可以包含随时间变动的单元。


接下来,我们提出一个快速的背景建模方法,该方法对于光照条件变化不大的室内的静止背景的场景效果很好。然后将介绍codebook方法,该方法虽然速度稍慢,但在室内外环境下都能工作的很好。也能适应周期性运动(比如树在风中摇曳)以及灯光缓慢变化或有规律的变化,并且对偶尔有前景目标移动的背景学习有很好的适应性。


第三、背景减除的缺点

虽然背景建模方法在简单的场景中能够达到较好的效果,但该方法受累于一个不常成立的假设:所有像素点是独立的。我们所描述的这种建模方法在计算像素变化时并没有考虑它相邻的像素。为了考虑它相邻的像素,我们需要建立一个多元模型,它把基本的像素独立模型扩展为包含了相邻像素的亮度的基本场景。在这种情况下,我们用相邻像素的亮度来区别相邻像素值的相对明暗。然后对单个像素的两种模型进行有效的学习:一个其周围像素是明亮的,另一个则是周围像素是暗淡的。但是,这样需要消耗两倍的内存和更多的计算量,因为当周围的像素是亮或暗的时,需要用不同的亮度值来表示,而且还要两倍的数据来填充这个双状态模型。


由于这些额外的开销,通常会避免使用复杂的模型。我们可以更有效地把精力投入到清楚那些错误的检测结果中。清除采用图像处理的方式(主要是cvErode(), cvDilate()和cvFloodFill()等)去掉那些孤立的像素。


第四、场景建模

以时间为基础将不变的前景模块缓慢转换为背景模块。当场景完全发生变化时我们还必须检测并建立一个新的模型。通常,一个场景模型可能包含许多层次,从“新的前景”到旧的前景再到背景,还可能有一些运动检测,这样,当一个目标移动时,我们可以识别其“真的”的前景(新位置)和“假的”的前景(其旧的位置,“空洞”)。


这样,一个新的前景目标就会放进“新前景”目标级别,标识为一个真目标或一个空洞。在没有任何前景物体的地方,我们将继续更新我们的背景模型。如果一个前景物体在给定的时间内没有发生移动,就将它降级为“旧的前景”,这里它的像素统计特性还将暂时学习直到它的学习模型融合进学习背景模型之中。


第五、像素片段

在转到为像素变化建模之前,先要对图像中的像素点在一段时间内如何变化有个概念。opencv有这样的函数,能够很容易对任意直线上的像素进行采样。线采样函数cvInitLineIterator()和CV_NEXT_LINE_POINT().


数据结构:CvLineIterator iter;   //采样迭代器
方法:
cvCreateFileCapture
初始化从文件中获取视频 


CvCapture* cvCreateFileCapture( const char* filename );
filename 
视频文件名。 
函数cvCreateFileCapture给指定文件中的视频流分配和初始化CvCapture结构。 


当分配的结构不再使用的时候,它应该使用cvReleaseCapture函数释放掉。
 
cvGrabFrame 
从摄像头或者视频文件中抓取帧 


int cvGrabFrame( CvCapture* capture );
capture 
视频获取结构指针。 
函数cvGrabFrame从摄像头或者文件中抓取帧。被抓取的帧在内部被存储。这个函数的目的是快速的抓取帧,这一点对同时从几个摄像头读取数据的同步是很重要的。被抓取的帧可能是压缩的格式(由摄像头/驱动定义),所以没有被公开出来。如果要取回获取的帧,请使用cvRetrieveFrame。
 
cvRetrieveFrame 
取回由函数cvGrabFrame抓取的图像


IplImage* cvRetrieveFrame( CvCapture* capture );
capture 
视频获取结构。 
函数cvRetrieveFrame返回由函数cvGrabFrame抓取的图像的指针。返回的图像不可以被用户释放或者修改。
 
InitLineIterator
初始化直线迭代器
 
int cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
                        CvLineIterator* line_iterator, int connectivity=8,
                        int left_to_right=0 );
img
用以获取直线的图像。
pt1
线段的第一个端点。
pt2
线段的第二个端点。
line_iterator
指向直线迭代状态结构体的指针。
connectivity
直线的邻接方式,4邻接或者8邻接。
left_to_right
标志值,指出扫描直线是从pt1和pt2外面最左边的点扫描到最右边的点(left_to_right≠0),还是按照指定的顺序,从pt1到pt2(left_to_right=0)。
函数cvInitLineIterator初始化直线迭代器并返回两个端点间点的数目。两个端点都必须在图像内部。在迭代器初始化以后,所有的在连接两个终点的栅栏线上的点,可以通过访问CV_NEXT_LINE_POINT点的方式获得。在线上的这些点使用4-邻接或者8-邻接的Bresenham算法计算得到。



0 0
原创粉丝点击