来源:网友投稿 浏览数:1208 关注:96人
大家好,近很多小伙伴在关注widthstep,以下是(www.liyan0123)小编整理的与widthstep相关的内容分享给大家,一起来看看吧。
本文目录一览:
三帧差分算法是相邻两帧差分算法的一种改进方法,它选取连续三帧视频图像进行差分运算,消除由于运动而显露背景影响,从而提取精确的运动目标轮廓信息。该算法的基本原理是是先选取视频图像序列中连续三帧图像并分别计算相邻两帧的差分图像,然后将差分图像通过选取适当的阈值进行二值化处理,得到二值化图像,后在每一个像素点得到的二值图像进行逻辑与运算,获取共同部分,从而获得运动目标的轮廓信息。
三帧差法的具体算法如下。
提取连续的三帧图像,I(k-1),I(k),I(k+1) 。
(1) d(k,k-1) [x,y] = | I(k)[x,y] - I(k-1)[x,y] |;
d(k,k+1)[x,y] = | I(k+1)[x,y] - I(k)[x,y] |;
(2) b(k,k-1)[x,y] = 1; if d(k,k-1) [x,y] = T;
b(k,k-1)[x,y] = 0; if d(k,k-1) [x,y] T;
b(k+1,k)[x,y] = 1 if d(k+1,k) [x,y] = T;
b(k+1,k)[x,y] = 0 if d(k+1,k) [x,y] T;
(3) B(k)[x,y] = 1 ; if b(k,k-1)[x,y] b(k+1,k)[x,y] == 1 ;
B(k)[x,y] = 0 ; if b(k,k-1)[x,y] b(k+1,k)[x,y] ==0 ;
比较关键的就是第2步的阈值T的选取问题,单纯用otsu算法分割貌似效果不太好,如果手动设置一个较小的值(如10)效果还行。
用otsu取阈值实现的一个三分差法代码。效果不是很好。
运行环境 VS2008+OpenCV2.0+windows XP .
[cpp] view plaincopyprint?#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include "cvaux.h"
#include iostream
#include cstdio
#include cstring
#include cmath
#include algorithm
#include queue
#include vector
#include windows.h
using namespace std;
#pragma comment(lib, "highgui200.lib")
#pragma comment(lib, "cv200.lib")
#pragma comment(lib, "cxcore200.lib")
#pragma comment(lib, "cvaux200.lib")
#define GET_IMAGE_DATA(img, x, y) ((uchar*)(img-imageData + img-widthStep * (y)))[x]
int T = 10;
int Num[300];
int Sum[300];
void InitPixel(IplImage * img, int _low, int _top)
{
memset(Num,0,sizeof(Num));
memset(Sum,0,sizeof(Sum));
_low = 255;
_top = 0;
for(int i = 0;i img-height;i++)
{
for(int j = 0;j img-width;j++)
{
int temp = ((uchar*)(img-imageData + img-widthStep*i))[j];
if(temp _low)
_low = temp;
if(temp _top)
_top = temp;
Num[temp] += 1;
}
}
for(int i = 1 ; i 256 ; i++)
{
Sum[i] = Sum[i-1]+ i*Num[i];
Num[i] += Num[i-1];
}
}
int otsu (IplImage *img)
{
int _low,_top,mbest=0;
float mn = img-height*img-width;
InitPixel(img,_low,_top);
float max_otsu = 0;
mbest = 0;
if( _low == _top)
mbest = _low;
else
{
for(int i = _low; i _top ; i++)
{
float w0 = (float)((Num[_top]-Num[i]) / mn);
float w1 = 1 - w0;
float u0 = (float)((Sum[_top]-Sum[i])/(Num[_top]-Num[i]));
float u1 = (float)(Sum[i]/Num[i]);
float u = w0*u0 + w1*u1;
float g = w0*(u0 - u)*(u0 - u) + w1*(u1 - u)*(u1 - u);
if( g max_otsu)
{
mbest = i;
max_otsu = g;
}
}
}
return mbest;
}
int main()
{
int ncount=0;
IplImage *image1=NULL;
IplImage *image2=NULL;
IplImage *image3=NULL;
IplImage *Imask =NULL;
IplImage *Imask1=NULL;
IplImage *Imask2=NULL;
IplImage *Imask3=NULL;
IplImage *mframe=NULL;
CvCapture *capture = cvCreateFileCapture("E:\\Motion\\IndoorGTTest2.avi");
//CvCapture *capture = cvCreateCameraCapture(0);
cvNamedWindow("src");
cvNamedWindow("dst");
cvNamedWindow("Imask1");
cvNamedWindow("Imask2");
cvNamedWindow("Imask3");
//cvCreateTrackbar("T","dst",T,255,0);
while(mframe=cvQueryFrame(capture))
{
DWORD start=GetTickCount();
if(ncount1000000000)
ncount=100;
ncount+=1;
if(ncount==1)
{
image1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
image2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
image3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
Imask =cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
Imask1=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
Imask2=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
Imask3=cvCreateImage(cvGetSize(mframe),IPL_DEPTH_8U,1);
cvCvtColor(mframe,image1,CV_BGR2GRAY);
}
if(ncount==2)
cvCvtColor(mframe,image2,CV_BGR2GRAY);
if(ncount=3)
{
if(ncount==3)
cvCvtColor(mframe,image3,CV_BGR2GRAY);
else
{
cvCopy(image2,image1);
cvCopy(image3,image2);
cvCvtColor(mframe,image3,CV_BGR2GRAY);
}
cvAbsDiff(image2,image1,Imask1);
cvAbsDiff(image3,image2,Imask2);
//cvShowImage("Imask1",Imask1);
//cvShowImage("Imask2",Imask2);
int mbest1 = otsu(Imask1);
cvSmooth(Imask1, Imask1, CV_MEDIAN);
cvThreshold(Imask1,Imask1,mbest1, 255, CV_THRESH_BINARY);
int mbest2 = otsu(Imask2);
cvSmooth(Imask2,Imask2, CV_MEDIAN);
cvThreshold(Imask2,Imask2,mbest2, 255, CV_THRESH_BINARY);
coutmbest1" "mbest2endl;
cvAnd(Imask1,Imask2,Imask);
/*cvErode(Imask, Imask);
cvDilate(Imask,Imask);*/
DWORD finish=GetTickCount();
// coutfinish-start"ms"endl;
cvShowImage("src",image2);
cvShowImage("dst",Imask);
}
char c = cvWaitKey(30);
if(c==27)
break;
}
return 0;
}
step 为图象像素行的实际宽度
不一定与width相符
比如 图像为 1024 *768
设置了感兴趣区域ROI为 400*200
那么这个感兴趣区域的图象宽度 为 200
要访问这个感兴趣区域的下一行,
图像数据指针的步长应该为 1024 而不是 200
这里 width 为 200 而 step为 1024
这个就是图像对齐的概念,widstep一般要=width,因为图像是严格按照4个字节的对齐,有时候相机样机会有width不规范比如659*494,这里width就是659,而widstep就是660,只有这样iplimage格式封装才会对齐。
以上就是widthstep的相关介绍,希望能对大家有所帮助。
获赞:132 | 收藏:17 | 发布时间:2024-05-11 00:50:21
原文链接:http://www.liyan0123.com/37731.html
=========================================
特别声明:以上内容来源于网友投稿,编辑整理发布,如有不妥之处,请与我方联系删除处理。