本文粗略的实现了中值滤波,将其用在了视频文件上。在此期间遇到了一些问题,中值滤波后出现的结果是一半彩色,一半灰色。然后我就想着应该是通道问题吧,因为实现的中值滤波代码,是处理一个通道的。于是我用cvSplit函数将每一帧的通道分离,分别进行处理,之后再通过函数cvMerge合成。最后实现的效果和试用cvSmooth函数处理一样的效果。
代码如下:(代码比较粗糙,欢迎指正)
#include "stdafx.h"
#include<highgui.h>
#include<cv.h>
#include <cxcore.h>
#include<stdio.h>
using namespace std;
bool FilterMid(IplImage* &image,int k)
{//中值滤波函数
IplImage *image2=cvCreateImage(cvSize(image->width,image->height),image->depth,1);
//IplImage *image2=cvCloneImage(image);
cvConvertScale(image,image2,1,0);
uchar *ImagePix=(uchar *)image2->imageData;
int m=(k-1)/2;
for (int x=m;x<image->height-m;++x)
for (int y=m;y<image->width-m;++y)
{
uchar PixArray[200];
int t=0;
for (int i=-m;i<m+1;++i)
{
for(int j=-m;j<m+1;++j)
{//赋值操作
PixArray[t++]=((uchar *)image->imageData)[(x+i)*image->widthStep+y+j];
}
}
for (int i=0;i<k*k-1;++i)
{
for(int j=0;j<k*k-i-1;++j)
{//起泡法快速排序
if (PixArray[j]>PixArray[j+1])
{
uchar k=PixArray[j];
PixArray[j]=PixArray[j+1];
PixArray[j+1]=k;
}
}
}
ImagePix[x*image->widthStep+y]=PixArray[(k*k-1)/2];
}
image=cvCloneImage(image2);//拷贝给原图像
cvReleaseImage(&image2);//销毁临时变量
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
IplImage* rawImage;
IplImage* rawImage2;
IplImage *gray1;
IplImage *gray2;
IplImage *gray3;
CvCapture* capture = cvCreateFileCapture("D:\\video\\video3.avi");
//初始化从文件中获取视频
if (!capture)
{
printf("Couldn't Open the file.");
return -1;
}
cvNamedWindow("raw");
cvNamedWindow("mid");
rawImage = cvQueryFrame(capture);
//这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合
cvShowImage("raw", rawImage);
gray1 = cvCreateImage(cvSize(rawImage->width, rawImage->height), IPL_DEPTH_8U, 1);
gray2 = cvCreateImage(cvSize(rawImage->width, rawImage->height), IPL_DEPTH_8U, 1);
gray3 = cvCreateImage(cvSize(rawImage->width, rawImage->height), IPL_DEPTH_8U, 1);
rawImage2=cvCreateImage(cvSize(rawImage->width,rawImage->height),rawImage->depth,3);
for(int i=0;;i++)
{
//rawImage2=cvCloneImage(rawImage);
cvConvertScale(rawImage,rawImage2,1,0);//将rawImage复制给rawImage2,像素位数不变
cvSplit(rawImage2, gray1, gray2, gray3, 0);
//得到的当前帧分割成3个单通道图像
FilterMid(gray1,3);
FilterMid(gray2,3);
FilterMid(gray3,3);
cvMerge(gray1,gray2,gray3,0, rawImage2);
cvShowImage("mid",rawImage2);
// cvSmooth(rawImage,rawImage2,3,3,0);
if(cvWaitKey(33)==27)
break;
if (!(rawImage = cvQueryFrame(capture)))
break;
else
{
cvShowImage("raw", rawImage);
cvShowImage("mid",rawImage2);
}
}
cvDestroyAllWindows();
cvReleaseImage(&rawImage);
cvReleaseImage(&rawImage2);
return 0;
}
参考博文:http://blog.sina.com.cn/s/blog_76da1d050100tjkl.html