视频二值化处理基本方法以及简单代码实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22562949/article/details/46047383

参考了网上的一些博客,基于opencv和vs2010的环境,将图像二值化应用到视频处理中去,下面将方法进行介绍。
方法一:
对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于127的
将像素值设为0(黑色),值大于等于127的像素值设为255(白色)。该方法的好处是计算
量少速度快。缺点更多首先阈值为127没有任何理由可以解释,其次完全不考虑图像的
像素分布情况与像素值特征。可以说该方法是史最弱智的二值处理方法一点也不为过。

方法二:
最常见的二值处理方法是计算像素的平均值K,扫描图像的每个像素值如像素值大于K
像素值设为255(白色),值小于等于K像素值设为0(黑色)。该方法相比方法一,阈值的
选取稍微有点智商,可以解释。但是使用平均值作为二值化阈值同样有个致命的缺点,
可能导致部分对象像素或者背景像素丢失。二值化结果不能真实反映源图像信息。
代码中大于平均值的设为0,小于设为255

方法三:http://en.wikipedia.org/wiki/Thresholding_(image_processing)
使用近似一维Means方法寻找二值化阈值,该方法的大致步骤如下:
1.一个初始化阈值T,可以自己设置或者根据随机方法生成。
2. 根据阈值图每个像素数据P(n,m)分为对象像素数据G1与背景像素数据G2。(n为
行,m为列)
3.G1的平均值是m1, G2的平均值是m2
4. 一个新的阈值T’ = (m1 + m2)/2
5. 回到第二步,用新的阈值继续分像素数据为对象与北京像素数据,继续2~4步,
直到计算出来的新阈值等于上一次阈值。

编程实现如下:
#include "highgui.h"
#include "cv.h"
//函数声明
void RGB_Gray_Typical(IplImage *tempFrame, IplImage *grayImage);
void BinaryFilter (IplImage *grayImage,IplImage *FliterImage);
void BinaryFilterTypical (IplImage *grayImage,IplImage *FliterImage);
void AverageBinaryFilter (IplImage *grayImage,IplImage *FliterImage);
void ThresholdBinaryFilter(IplImage *grayImage,IplImage *FliterImage);
int main()
{
//确定要读入的AVI视频
CvCapture *capture = cvCreateFileCapture("E:\\新建文件夹\\行车视频.avi");
//将视频文件的下一帧加载到内存
IplImage *tempFrame= cvQueryFrame(capture);
IplImage *grayImage,*FliterImage;
//创建头并分配数据,取与这一帧图大小一样的尺寸,数据类型为无符号8位整型,单通道
grayImage = cvCreateImage(cvSize(tempFrame->width, tempFrame->height),8,1);
    FliterImage=cvCreateImage(cvSize(tempFrame->width,tempFrame->height),8,1);
while (IplImage *tempFrame = cvQueryFrame(capture))
{
cvShowImage("原始视频",tempFrame); //播放原视频
RGB_Gray_Typical(tempFrame, grayImage);//得到灰度图
cvShowImage("灰度视频",grayImage);
        BinaryFilter(grayImage,FliterImage); 
char c = cvWaitKey(33);  
        if (c == 27)  
        {  
              return 0;  
        }  
cvWaitKey(10);
}
cvReleaseCapture(&capture);
cvReleaseImage(&grayImage);
cvReleaseImage(&FliterImage);
cvDestroyAllWindows();
}
//二值化有很多方法,这里只调用一个二值化函数
void BinaryFilter (IplImage *grayImage,IplImage *FliterImage)
{        
//BinaryFilterTypical(grayImage,FliterImage); 

//AverageBinaryFilter(grayImage,FliterImage); 
ThresholdBinaryFilter(grayImage,FliterImage); 
}
void RGB_Gray_Typical(IplImage *tempFrame, IplImage *grayImage)
{    
for(int j=0; j<tempFrame->height; j++)  
    for(int i=0; i<tempFrame->width; i++)  
    {    
//int liv_size = j * img->width + i;//测试循环多少次    
uchar *data=( uchar *)(tempFrame->imageData );
   int step=tempFrame->widthStep;
//得到某个像素点bgr三个通道的像素值
        double B = (double)data[j*step + i*3+0];     //B分量  
        double G= (double)data[j*step + i*3 + 1]; //G分量  
        double R = (double)data[j*step + i*3 + 2]; //R分量 
//用灰度公式,计算出这个像素点转换后的灰度值GRAY
double GRAY = (double)(0.299 * R+ 0.587 * G + 0.114 * B+0.5);  
//把GRAY的值赋给它对应的内存单元
long int index= j*tempFrame->width + i;
    grayImage->imageData[index] = GRAY;
//cout<<"liv_size = "<<liv_size<<endl;
}
}
//方法一

void BinaryFilterTypical (IplImage *grayImage,IplImage *FliterImage)
{
for(int j=0; j<grayImage->height; j++)  
    for(int i=0; i<grayImage->width; i++)  
{
uchar *data1=( uchar *)(grayImage->imageData );
if(data1[j*grayImage->width + i]>127)
{ FliterImage->imageData[j*grayImage->width + i]=255;}
else
{ FliterImage->imageData[j*grayImage->width + i]=0;}
}
          cvShowImage("二值化视频",FliterImage);
 

}

//方法二
void AverageBinaryFilter (IplImage *grayImage,IplImage *FliterImage)
{               
          
  uchar *data1=( uchar *)(grayImage->imageData );
                uchar sum=0; 
                for(int j=0; j<grayImage->height; j++)  
{
                for(int i=0; i<grayImage->width; i++)  
                 {       
 
     sum=uchar(sum+data1[j*grayImage->width + i]);  
       }
}
uchar Average=uchar(sum/(grayImage->height*grayImage->width));
for(int j=0; j<grayImage->height; j++)  
{
                for(int i=0; i<grayImage->width; i++)  
                 {   
                if(data1[j*grayImage->width + i]>Average)
                         { FliterImage->imageData[j*grayImage->width + i]=0;}
                  else
                          { FliterImage->imageData[j*grayImage->width + i]=255;}
                  }
}
cvShowImage("平均二值化视频",FliterImage);
}
//方法三
void ThresholdBinaryFilter(IplImage *grayImage,IplImage *FliterImage)
{
        uchar inithreshold = 127;  //初始化阈值设置为127
uchar finalthreshold =0;
//uchar newthreshold;
uchar sum1=0;
uchar sum2=0; 
int number1=0;
int number2=0;
uchar *data1=( uchar *)(grayImage->imageData );
while(finalthreshold != inithreshold) {  
            finalthreshold = inithreshold;  
//统计大于阈值的像素值总和,和小于阈值的像素值总和
for(int j=0; j<grayImage->height; j++)  
{
           for(int i=0; i<grayImage->width; i++)  
    {
            
            if(data1[j*grayImage->width + i]>inithreshold)
            {   sum1=uchar(sum1+data1[j*grayImage->width + i]);   }
            else
            {  sum2=uchar(sum2+data1[j*grayImage->width + i]);        }
  }
}
//统计大于阈值的个数,小于阈值的像素个数
                       for(int j=0; j<grayImage->height; j++)  
          {
                            for(int i=0; i<grayImage->width; i++)  
                     {
            
                               if(data1[j*grayImage->width + i]>inithreshold)
                                    { number1=number1+1; }
                                 else
                                      {  number2=number2+1; }
  }
}
    //分别计算这两种点的均值,再除以2,作为下一次的阈值
                         uchar Average1=uchar(sum1/number1);
uchar Average2=uchar(sum2/number2);
                        inithreshold =uchar(( Average1+Average2)/2);

for(int j=0; j<grayImage->height; j++)  
          {
                            for(int i=0; i<grayImage->width; i++)  
                     {
               if(data1[j*grayImage->width + i]>inithreshold)
                                   { FliterImage->imageData[j*grayImage->width + i]=0;}
                               else
                                    { FliterImage->imageData[j*grayImage->width + i]=255;}
}
  }
}
cvShowImage("阈值二值化视频",FliterImage);
      }



猜你喜欢

转载自blog.csdn.net/qq_22562949/article/details/46047383
今日推荐