视频前景目标提取
1.
2. #include
3. #include
4. #include
5. #include
6. using namespace cv;
7. using namespace std;
8.
9. int main()
10. {
11.
12.
//int argc, char* argv[]
CvCapture *capture = cvCreateFileCapture("E:\\数学建模\\input2.avi
");
13.
IplImage *img, *img_gray, *img_cny, *back, *fore;//原图像、灰度图像、
边缘检测得到的图像、背景图像、前景图像
14.
15.
16.
17.
18.
19.
20.
CvVideoWriter *writer=NULL;
double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
CvSize size = cvSize(
(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
writer = cvCreateVideoWriter("E:\\数学建模\\input2out.avi", CV_FOU
RCC('M','J','P','G'), fps, size, 0);
21.
22.
23.
24.
25.
26.
27.
int width, height;//图像的长、宽
int cnt = 0; //视频帧数
img = cvQueryFrame(capture);
cnt++;
width = img->width; height = img->height;
vector< vector > mean(width*height), sd(width*height), w(w
idth*height);
28.
29.
30.
31.
32.
33.
34.
35.
img_gray = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
img_cny = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
back = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
fore = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
cvCvtColor(img, img_gray, CV_BGR2GRAY);
cvCopy(img_gray, back);
//初始化混合高斯背景模型
int K = 5, sd_init = 16, T = 200, match = 0;//高斯分布的个数、标准差
的初始值 帧数阈值 匹配参数
36.
double w_init = 0.005, D = 2.5, alph, p, threold = 0.7;//权重的初始
值、置信参数、学习速率、参数更新速率、预定阈值(用于选取背景模型)
37.
38.
39.
40.
41.
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
mean[i*width + j].push_back((uchar)img_gray->imageData[i*widt
h + j]);
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
sd[i*width + j].push_back(sd_init);
w[i*width + j].push_back(1);
}
}
IplImage* logpolar_frame = cvCreateImage(size, IPL_DEPTH_8U, 3);
while (1)
{
img = cvQueryFrame(capture);
if (!img) break;
cvCvtColor(img, img_gray, CV_BGR2GRAY);
cnt++;
//计算学习速率
if (cnt < T) alph = (double)1 / (2 * cnt);
else alph = (double)1 / (2 * T);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
match = 0;
int len = mean[i*width + j].size();
for (int k = 0; k < len; k++)
{
//判断一个像素是否与背景模型匹配
if (fabs((uchar)img_gray->imageData[i*width + j] - mea
n[i*width + j][k]) < D*sd[i*width + j][k])
69.
70.
71.
72.
alph;
73.
74.
{
match = 1;
//更新权重、均值、标准差
w[i*width + j][k] = (1 - alph)*w[i*width + j][k] +
p = alph / w[i*width + j][k];
mean[i*width + j][k] = (1 - p)*mean[i*width + j][k]
+ p*(uchar)img_gray->imageData[i*width + j];
75.
sd[i*width + j][k] = sqrt((1 - p)*sd[i*width + j]
[k] * sd[i*width + j][k] + p*pow((uchar)img_gray->imageData[i*width + j]
- mean[i*width + j][k], 2));
w[i*width + j][k] = (1 - alph)*w[i*width + j][k];
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
}
else
{
}
}
if (match == 0)
{
//增加新的背景模型
if (len < K)
{
mean[i*width + j].push_back((uchar)img_gray->image
Data[i*width + j]);
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
sd[i*width + j].push_back(sd_init);
w[i*width + j].push_back(w_init);
}
//更改权重最小的背景模型
else
{
int min = 0;
double tmp = w[i*width + j][0];
for (int k = 1; k < len; k++)
{
min = k;
tmp = w[i*width + j][k];
if (tmp > w[i*width + j][k])
{
}
mean[i*width + j][min] = (uchar)img_gray->imag
}
eData[i*width + j];
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
}
sd[i*width + j][min] = sd_init;
w[i*width + j][min] = w_init;
}
//每隔50 帧 删除权重最小的高斯分布
if (cnt % 50 == 0)
{
vector::iterator it_w, it_sd, it_mean;
it_w = w[i*width + j].begin();
it_sd = sd[i*width + j].begin();
115.
116.
it_mean = mean[i*width + j].begin();
for (; it_w != w[i*width + j].end() && it_sd != sd
[i*width + j].end() && it_mean != mean[i*width + j].end();)
{
if (*it_w < w_init && (*it_w / *it_sd) < (w_ini
it_w = w[i*width + j].erase(it_w);
it_sd = sd[i*width + j].erase(it_sd);
it_mean = mean[i*width + j].erase(it_mean);
117.
118.
t / sd_init))
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
tmp += w[i*width + j][k];
}
it_w++;
it_sd++;
it_mean++;
{
}
else
{
}
}
//权重归一化
len = mean[i*width + j].size();
double tmp = 0;
for (int k = 0; k < len; k++)
{
}
for (int k = 0; k < len; k++)
{
}
//计算各背景模型的优先级,并以从大到小的顺序排序
double *rand;//优先级
int *rand_ind;//排序后的优先级索引
rand = (double *)malloc(sizeof(double)*len);
rand_ind = (int *)malloc(sizeof(int)*len);
for (int k = 0; k < len; k++)
{
}
for (int k = 1; k< len; k++)
{
for (int l = 0; l < k; l++)
{
w[i*width + j][k] /= tmp;
rand[k] = w[i*width + j][k] / sd[i*width + j][k];
rand_ind[k] = k;
if (rand[k] > rand[l])
{
double rand_tmp = rand[k];
rand[k] = rand[l];
rand[l] = rand_tmp;
double rand_ind_tmp = rand_ind[k];
rand_ind[k] = rand_ind[l];
rand_ind[l] = rand_ind_tmp;
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
}
}
int temp = rand_ind[k];
sum += w[i*width + j][temp];
if (sum>threold)
{
}
}
double sum = 0;
int B;
for (int k = 0; k < len; k++)
{
}
match = 0;
back->imageData[i*width + j] = 0;
//求背景模型
for (int k = 0; k <= B; k++)
{
B = k;
break;
int temp = rand_ind[k];
back->imageData[i*width + j] += w[i*width + j][tem
p] * mean[i*width + j][temp];
189.
190.
191.
192.
193.
194.
195.
}
/*
//求前景图像
for (int k = 0; k <= B; k++)
{
int temp = rand_ind[k];
if (fabs((uchar)img_gray->imageData[i*width + j] - mea
n[i*width + j][temp]) < D*sd[i*width + j][temp])
196.
197.
198.
{
match = 1;
break;
199.
200.
201.
202.
}
}
if (match == 1) fore->imageData[i*width + j] = 0;
else fore->imageData[i*width + j] = (uchar)img_gray->i
mageData[i*width + j];
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
}
}
cvAbsDiff(img_gray, back, fore);
cvCanny(img_gray, img_cny, 40, 100,3);
cvShowImage("canny", img_cny);
cvAnd(img_cny, fore, fore);
cvDilate(fore, fore, NULL, 3);
cvErode(fore, fore, NULL, 3);
cvThreshold(fore, fore, 55, 255, CV_THRESH_BINARY);
cvWriteFrame(writer, fore);
*/
free(rand);
free(rand_ind);
}
cvDestroyAllWindows();
cvReleaseCapture(&capture);
cvReleaseImage(&img_gray);
cvReleaseImage(&fore);
cvReleaseImage(&back);
cvReleaseImage(&img_cny);
cvReleaseVideoWriter(&writer);
return (0);
}
cvShowImage("fore", fore);
cvShowImage("back", back);
cvShowImage("src", img);
char s = cvWaitKey(1);
if (s == 27) break;