图像外推算法

#include "stdafx.h"
#include "ShapeExtend.h"

#include "MainFrm.h"
#include "NewFeatureofStormDoc.h"
#include "NewFeatureofStormView.h"


bool CShapeExtend::FlagOfRead=TRUE;
CShapeExtend::CShapeExtend()
 ://反射率对应的颜色表
 Refminus5to0(156,156,156),Ref0to5(118,118,118),Ref5to10(170,170,254),
 Ref10to15(140,140,238),Ref15to20(112,112,200),Ref20to25(144,250,0),
 Ref25to30(0,186,0),Ref30to35(112,254,254),Ref35to40(96,208,208),
 Ref40to45(96,96,254),Ref45to50(0,0,218),Ref50to55(0,0,174),
 Ref55to60(254,0,0),Ref60to65(254,254,160),Ref65to70(254,0,230),RefBlack(0,0,0)
 //, topbound(0)
 //, bottombound(0)
 //, leftbound(0)
 //, rightbound(0)
 //, rectcenter(0)
 , vecx(0)
 , vecy(0)
 , FlagOfReadBaseData(false)
 , crtcellorgpt(0)
 , lstcellorgpt(0)
 , nextrealorpt(0)
 , ccoeff(0)
 {
  
 
 
}

CShapeExtend::~CShapeExtend()
{
 
}
//============= 将原图像上的像素赋值给目标图像 =======================
//( 其中full表示是否完全复制,当为False时,原图像的黑色像素点不被复制 )
void CShapeExtend::MatCopy(const Mat& Src,Mat Dst,BOOL full)
{
 if (Src.data==NULL&&Dst.data==NULL)
 {
  //MessageBox("赋值时图像为空");
  return;
 }
 
 for (int Row=0;Row<Src.rows;Row++)
 {
  for (int Col=0;Col<Src.cols;Col++)
  {
   Point2i poi(Col,Row);
   
   if (full)
   {
    Dst.at<Vec3b>(poi)=Src.at<Vec3b>(poi);
   }
   else
   {
     Dst.at<BYTE>(poi)=Src.at<BYTE>(poi);
   }
  
  }
 }
}

//========从反射率值得到对应的颜色值============
Vec3b CShapeExtend::ReflectionValue(const int Ref)
{
 if (Ref>=-5&&Ref<0)
 {
  return Refminus5to0;
 }
 else if(Ref>=0&&Ref<5)
 {
  return Ref0to5;

 }
 else if(Ref>=5&&Ref<10)
 {
  return Ref5to10;
 }
 else if(Ref>=10&&Ref<15)
 {
  return Ref10to15;
 }
 else if(Ref>=15&&Ref<20)
 {
  return Ref15to20;
 }
 else if(Ref>=20&&Ref<25)
 {
  return Ref20to25;
 }
 else if(Ref>=25&&Ref<30)
 {
  return Ref25to30;
 }
 else if(Ref>=30&&Ref<35)
 {
  return Ref30to35;
 }
 else if(Ref>=35&&Ref<40)
 {
  return Ref35to40;
 }
 else if(Ref>=40&&Ref<45)
 {
  return Ref40to45;
 }
 else if(Ref>=45&&Ref<50)
 {
  return Ref45to50;
 }
 else if(Ref>=50&&Ref<55)
 {
  return Ref50to55;
 }
 else if(Ref>=55&&Ref<60)
 {
  return Ref55to60;
 }
 else if(Ref>=60&&Ref<65)
 {
  return Ref60to65;
 }
 else if(Ref>=65&&Ref<70)
 {
  return Ref65to70;
 }
 else
 {
  return RefBlack;
 }
}

//===============从像素颜色取得对应的反射率值=====================
//返回值为反射率范围的起始数值
int CShapeExtend::GetReflectionValue(Vec3b color)
{
 if(color==RefBlack)
 {
  return -10;
 }
 else if (color==Refminus5to0)
 {
  return -5;
 }
 else if(color==Ref0to5)
 {
  return 0;
 }
 else if(color==Ref5to10)
 {
  return 5;
 }
 else if(color==Ref10to15)
 {
  return 10;
 }
 else if(color==Ref15to20)
 {
  return 15;
 }
 else if(color==Ref20to25)
 {
  return 20;
 }
 else if(color==Ref25to30)
 {
  return 25;
 }
 else if(color==Ref30to35)
 {
  return 30;
 }
 else if(color==Ref35to40)
 {
  return 35;
 }
 else if(color==Ref40to45)
 {
  return 40;
 }
 else if(color==Ref45to50)
 {
  return 45;
 }
 else if(color==Ref50to55)
 {
  return 50;
 }
 else if(color==Ref55to60)
 {
  return 55;
 }
 else if(color==Ref60to65)
 {
  return 60;
 }
 else if(color==Ref65to70)
 {
  return 65;
 }
}

//================去除关注反射率范围外的反射率值=========
//反射率值过低的置成黑色,过高的置成阈值上限的颜色
void CShapeExtend::Filter(Mat Mat2P)
{
 for (int Row=0;Row<Mat2P.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<Mat2P.cols;++Col)
  { 
   Point2i dot(Col,Row);
   int value=GetReflectionValue(Mat2P.at<Vec3b>(dot));
   if (value<25)//反射率在25以下的置成黑色
   {
    Mat2P.at<Vec3b>(dot)=RefBlack;
   }
   else if (value>55)//反射率在55以上的置成Ref55to60
   {
    Mat2P.at<Vec3b>(dot)=Ref55to60;
   }
  }
 }
}

//===================得到图像的7层单反射率层=============
void CShapeExtend::GetLayer(Mat srcMat)
{
 Mat25.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mat30.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mat35.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mat40.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mat45.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mat50.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mat55.create(srcMat.rows,srcMat.cols,CV_8UC3);
 Mattemp.create(srcMat.rows,srcMat.cols,CV_8UC3);
 MatCopy(srcMat,Mat25,1);
 MatCopy(srcMat,Mat30,1);
 MatCopy(srcMat,Mat35,1);
 MatCopy(srcMat,Mat40,1);
 MatCopy(srcMat,Mat45,1);
 MatCopy(srcMat,Mat50,1);
 MatCopy(srcMat,Mat55,1);
 MatCopy(srcMat,Mattemp,1);
 vector<Mat> MatLayer;  //定义Mat容器存放7层Mat图层
 MatLayer.clear();
 MatLayer.push_back(Mat25); //把7个Mat图层压入容器
 MatLayer.push_back(Mat30);
 MatLayer.push_back(Mat35);
 MatLayer.push_back(Mat40);
 MatLayer.push_back(Mat45);
 MatLayer.push_back(Mat50);
 MatLayer.push_back(Mat55);
 vector<Mat>::iterator ite_mat;//指向Mat容器的迭代器

 //vector<const char*> WindowName;//定义一容器存放窗口名称
 //const char* window1="25DBz分届图层";
 //const char* window2="30DBz分届图层";
 //const char* window3="35DBz分届图层";
 //const char* window4="40DBz分届图层";
 //const char* window5="45DBz分届图层";
 //const char* window6="50DBz分届图层";
 //const char* window7="55DBz分届图层";
 //WindowName.clear();
 //WindowName.push_back(window1);
 //WindowName.push_back(window2);
 //WindowName.push_back(window3);
 //WindowName.push_back(window4);
 //WindowName.push_back(window5);
 //WindowName.push_back(window6);
 //WindowName.push_back(window7);
 //vector<const char*>::iterator ite_win; //指向窗口名称容器的迭代器
 //ite_win= WindowName.begin();//令其指向容器起始位置

 int layer=20; //定义分层的阈值
 for (ite_mat= MatLayer.begin();ite_mat!= MatLayer.end();ite_mat++)
 {
  layer+=5;//意味着第一层从25开始,每次+5
  Mattemp=*ite_mat;//每一层Mat赋值到一个Mat缓存中
  for (int Row=0;Row<Mattemp.rows;++Row) //开始遍历图像
  {
   for (int Col=0;Col<Mattemp.cols;++Col)
   { 
    Point2i dot(Col,Row);
    int value=GetReflectionValue(Mattemp.at<Vec3b>(dot));
    if (value<layer)//反射率在layer阈值以下的置成黑色
    {
     Mattemp.at<Vec3b>(dot)=RefBlack;
    }
    else Mattemp.at<Vec3b>(dot)=ReflectionValue(layer);//其余都置成layer层的颜色

   }
  }
  *ite_mat=Mattemp;// 处理后的图像保存回Mat容器中每一对应层
  //cv::namedWindow(*ite_win,CV_WINDOW_AUTOSIZE);//弹出窗口显示每一层
  //cv::imshow(*ite_win,*ite_mat);
  //ite_win++;


 }
}


void CShapeExtend::Threshold(Mat Mat2GT,Mat ThresMat)//要进行二值化的Mat图
{
 ThresMat.setTo(0);
 for (int j=0;j<Mat2GT.rows;j++)
 {
  for (int i=0;i<Mat2GT.cols;i++)
  {
   Point2i dot(i,j);
   Vec3b black(0,0,0);
   Vec3b value=Mat2GT.at<Vec3b>(dot);
   if (value!=black)
   {
    ThresMat.at<BYTE>(dot)=255;
   }
  }
 }
}

 


//void CShapeExtend::GetRect(Mat mat)
//{
// //找顶部边界线
// int boundthres=5;
// for (int Row=0;Row<mat.rows;++Row)//从顶部开始遍历图像
// {
//  int count=0;
//  for (int Col=0;Col<mat.cols;++Col)
//  { 
//   Point2i dot(Col,Row);
//   if (mat.at<BYTE>(dot)==0)
//    continue;
//   else
//    count++;
//  } 
//  if(count>boundthres)           //第一次出现大于5个像素点,即跳出记为顶部
//  {
//      topbound=Row;
//   break;
//  }
// }
// //找顶部边界线
// for (int Row=mat.rows-1;Row>=0;Row--)// 从底部开始遍历图像
// {
//  int count=0;
//  for (int Col=0;Col<mat.cols;++Col)
//  { 
//   Point2i dot(Col,Row);
//   if (mat.at<BYTE>(dot)==0)
//    continue;
//   else
//    count++;
//  } 
//  if(count>boundthres)
//  {
//   bottombound=Row;
//   break;
//  }
// }
//
// //左边界搜寻
// for (int Col=0;Col<mat.cols;++Col)//从左侧开始遍历图像
// {
//  int count=0;
//  for (int Row=0;Row<mat.rows;++Row)
//  { 
//   Point2i dot(Col,Row);
//   if (mat.at<BYTE>(dot)==0)
//    continue;
//   else
//    count++;
//  } 
//  if(count>boundthres)           //第一次出现大于5个像素点,即跳出记为左侧边界
//  {
//   leftbound=Col;
//   break;
//  }
// }
//
// //右边界搜寻
// for (int Col=mat.cols-1;Col>=0;Col--)//从左侧开始遍历图像
// {
//  int count=0;
//  for (int Row=0;Row<mat.rows;++Row)
//  { 
//   Point2i dot(Col,Row);
//   if (mat.at<BYTE>(dot)==0)
//    continue;
//   else
//    count++;
//  } 
//  if(count>boundthres)           //第一次出现大于5个像素点,即跳出记为右侧边界
//  {
//   rightbound=Col;
//   break;
//  }
// }
// rectcenter.x=(leftbound+rightbound)/2;
// rectcenter.y=(topbound+bottombound)/2;
//}


//void CShapeExtend::VectorFix(Mat Mat2fix)
//{
// Matfix.create(Mat2fix.rows,Mat2fix.cols,CV_8UC1);
// Matfix.setTo(0);
// for (int Row=0;Row<Mat2fix.rows;++Row)//开始遍历图像
// {
//  for (int Col=0;Col<Mat2fix.cols;++Col)
//  { 
//   Point2i dot(Col,Row);
//   Point2i dotfix(Col+vecx,Row+vecy);
//   if(Mat2fix.at<BYTE>(dot)==255)
//      Matfix.at<BYTE>(dotfix)=255;
//  }
// }
//}


void CShapeExtend::GetDifferMat(Mat Lastmat, Mat Currentmat)
{
 /*GetRect(Lastmat);
 Point2i LastCenDot=rectcenter;
 GetRect(Currentmat);
 Point2i CurrentCenDot=rectcenter;
 vecx=CurrentCenDot.x-LastCenDot.x;
 vecy=LastCenDot.y-LastCenDot.y;*/
 //VectorFix(Lastmat); //LastMat经过坐标修订存到了Matfix


 //获取云团消长区域
 LayerGrow.create(Lastmat.rows,Lastmat.cols,CV_8UC1);
 LayerDie.create(Lastmat.rows,Lastmat.cols,CV_8UC1);
 for (int Row=0;Row<Lastmat.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<Lastmat.cols;++Col)
  { 
   Point2i dot(Col,Row);
   int valuecurrent=Currentmat.at<BYTE>(dot);
   int valuelast=Lastmat.at<BYTE>(dot);
   int delta=valuecurrent-valuelast;
   if( delta==255)
   {
    LayerGrow.at<BYTE>(dot)=255;
    LayerDie.at<BYTE>(dot)=0;
   }
   else if( delta==0)
   {
    LayerGrow.at<BYTE>(dot)=0;
    LayerDie.at<BYTE>(dot)=0;
   }

   else
   {
    LayerGrow.at<BYTE>(dot)=0;
    LayerDie.at<BYTE>(dot)=255;
   }
  }
 }
}


void CShapeExtend::GetExtractContours(Mat srcMat, Mat dstMat, double thres)//提取出srcMat中面积大于thres的区域储存于dstMat中
{
 Mat GrowContours;//用于储存增长区域轮廓线
 GrowContours.create(srcMat.rows,srcMat.cols,CV_8UC1);
 MatCopy(srcMat,GrowContours,0);//findcontours后GrowContours被破坏,而srcMat保存完好
 vector<vector<Point>> grow_contours;//存储连通区域
 vector<vector<Point>>::iterator ite_contours;//指向vector<Point>容器的迭代器
 cv::findContours(GrowContours,grow_contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//只检测外轮廓,存储所有的轮廓点,相邻的两个点的像素位置差不超过1
 vector<vector<Point>> extract_contours;
 extract_contours.clear();
 for (ite_contours= grow_contours.begin();ite_contours!= grow_contours.end();ite_contours++)
 {
  double s=contourArea(Mat(*ite_contours));
  if(s>thres)
    {
     extract_contours.push_back(*ite_contours);
 
            /*  写入TXT检验
      CFile file;
      file.Open("c:\\1.txt",CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate);
      CString str ;
      str.Format(_T("%lf "),s);
      file.SeekToEnd();
      file.Write(str,str.GetLength());
      file.Close();
      */
     }
    }
 
 
 Scalar color(255,255,0);//Color of contours
 cv::drawContours(dstMat,extract_contours,-1,color,-1);//全部联通域内部填充轮廓内部
}


void CShapeExtend::GetShakeContours9(Mat srcMat, Mat ShakeMat)
{
 for (int Row=1;Row<srcMat.rows-1;++Row)//      抛去边缘效应所以少一圈,从1到(行-1),从1到(列-1)
 {
  for (int Col=1;Col<srcMat.cols-1;++Col)
  {
   Point2i dot(Col,Row);
   Point2i dot1(Col-1,Row-1);
   Point2i dot2(Col,Row-1);
   Point2i dot3(Col+1,Row-1);
   Point2i dot4(Col+1,Row);
   Point2i dot5(Col+1,Row+1);
   Point2i dot6(Col,Row+1);
   Point2i dot7(Col-1,Row+1);
   Point2i dot8(Col-1,Row);
   if( srcMat.at<BYTE>(dot)==255)
   {
    //if ((dot.x>0)&&(dot.x<srcMat.cols)&&(dot.y>0)&&(dot.y<srcMat.rows))
    //{
     //ShakeMat.at<BYTE>(dot1)=255;
     ShakeMat.at<BYTE>(dot2)=255;
     //ShakeMat.at<BYTE>(dot3)=255;
     ShakeMat.at<BYTE>(dot4)=255;
     //ShakeMat.at<BYTE>(dot5)=255;
     ShakeMat.at<BYTE>(dot6)=255;
     //ShakeMat.at<BYTE>(dot7)=255;
     ShakeMat.at<BYTE>(dot8)=255;
    //}
    
   }
  }
 }
}


void CShapeExtend::GetShakeContours25(Mat srcMat, Mat ShakeMat)
{
 for (int Row=2;Row<srcMat.rows-2;++Row)//      抛去边缘效应所以少一圈
 {
  for (int Col=2;Col<srcMat.cols-2;++Col)
  {
   Point2i dot(Col,Row);
   Point2i dot1(Col-1,Row-1);
   Point2i dot2(Col,Row-1);
   Point2i dot3(Col+1,Row-1);
   Point2i dot4(Col+1,Row);
   Point2i dot5(Col+1,Row+1);
   Point2i dot6(Col,Row+1);
   Point2i dot7(Col-1,Row+1);
   Point2i dot8(Col-1,Row);
   Point2i dot9(Col-2,Row);
   Point2i dot10(Col,Row-2);
   Point2i dot11(Col+2,Row);
   Point2i dot12(Col,Row+2);
   if( srcMat.at<BYTE>(dot)==255)
   {
        //ShakeMat.at<BYTE>(dot1)=255;
     ShakeMat.at<BYTE>(dot2)=255;
     //ShakeMat.at<BYTE>(dot3)=255;
     ShakeMat.at<BYTE>(dot4)=255;
     //ShakeMat.at<BYTE>(dot5)=255;
     ShakeMat.at<BYTE>(dot6)=255;
     //ShakeMat.at<BYTE>(dot7)=255;
     ShakeMat.at<BYTE>(dot8)=255;
     ShakeMat.at<BYTE>(dot9)=255;
     ShakeMat.at<BYTE>(dot10)=255;
     ShakeMat.at<BYTE>(dot11)=255;
     ShakeMat.at<BYTE>(dot12)=255;

   }
  }
 }
}


void CShapeExtend::SynthesizeContours(Mat srcMat, Mat Shake9, Mat Shake25,Mat dstMat)
{
 for (int Row=0;Row<srcMat.rows;++Row)//
 {
  for (int Col=0;Col<srcMat.cols;++Col)
  {
   Point2i dot(Col,Row);
   if( srcMat.at<BYTE>(dot)==255||Shake9.at<BYTE>(dot)==255||Shake25.at<BYTE>(dot)==255)
   {
    dstMat.at<BYTE>(dot)=255;
   }
  }
 }
}


void CShapeExtend::GetSingleExtrap(Mat LastMat, Mat CurrentMat, Mat SingleExtrap)
{
 GetDifferMat(LastMat,CurrentMat);//获得增长消亡区域图层
 
 Mat ExtractContours9;
 ExtractContours9.create(LastMat.rows,LastMat.cols,CV_8UC1);
 ExtractContours9.setTo(0);
 Mat ShakeContours9;
 ShakeContours9.create(LastMat.rows,LastMat.cols,CV_8UC1);
 ShakeContours9.setTo(0);
 Mat ExtractContours25;
 ExtractContours25.create(LastMat.rows,LastMat.cols,CV_8UC1);
 ExtractContours25.setTo(0);
 Mat ShakeContours25;
 ShakeContours25.create(LastMat.rows,LastMat.cols,CV_8UC1);
 ShakeContours25.setTo(0);

 GrowExtrap.create(LastMat.rows,LastMat.cols,CV_8UC1);
 GrowExtrap.setTo(0);
 GetExtractContours(LayerGrow,ExtractContours9,9);
 GetShakeContours9(ExtractContours9,ShakeContours9);
 GetExtractContours(LayerGrow,ExtractContours25,25);
 GetShakeContours25(ExtractContours25,ShakeContours25);
 SynthesizeContours( LayerGrow,ShakeContours9,ShakeContours25,GrowExtrap);
 /*cv::namedWindow("新生云区域的图片",CV_WINDOW_AUTOSIZE);
 cv::imshow("新生云区域的图片",LayerGrow);
 cv::namedWindow("新生云区域的图片9",CV_WINDOW_AUTOSIZE);
 cv::imshow("新生云区域的图片9",ExtractContours9);
 cv::namedWindow("新生云区域的图片25",CV_WINDOW_AUTOSIZE);
 cv::imshow("新生云区域的图片25",ExtractContours25);
 cv::namedWindow("新生区域外推图片",CV_WINDOW_AUTOSIZE);
 cv::imshow("新生区域外推图片",GrowExtrap);*/
 
 

 
 DieExtrap.create(LastMat.rows,LastMat.cols,CV_8UC1);
 DieExtrap.setTo(0);
 ExtractContours9.setTo(0);
 ShakeContours9.setTo(0);
 ExtractContours25.setTo(0);
 ShakeContours25.setTo(0);
 GetExtractContours(LayerDie,ExtractContours9,5);
 GetShakeContours9(ExtractContours9,ShakeContours9);
    GetExtractContours(LayerDie,ExtractContours25,25);
 GetShakeContours25(ExtractContours25,ShakeContours25);
 SynthesizeContours( LayerDie,ShakeContours9,ShakeContours25,DieExtrap);

 //======================外推图像显示=============================
  Mat ExtrapMat;
 ExtrapMat.create(LastMat.rows,LastMat.cols,CV_8UC1);
   MatCopy(CurrentMat,ExtrapMat);
 for (int Row=0;Row<ExtrapMat.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<ExtrapMat.cols;++Col)
  {
   Point2i dot(Col,Row);
   if(GrowExtrap.at<BYTE>(dot)==255&&ExtrapMat.at<BYTE>(dot)==0)
   {
    ExtrapMat.at<BYTE>(dot)=255;
   }
   if( DieExtrap.at<BYTE>(dot)==255&&ExtrapMat.at<BYTE>(dot)==255)
   {
    ExtrapMat.at<BYTE>(dot)=0;
   }
  }
 }
 //VectorFix(ExtrapMat);
 //Matfix.create(ExtrapMat.rows,ExtrapMat.cols,CV_8UC1);
 //MatCopy(ExtrapMat,Matfix,0);
 MatCopy(ExtrapMat,SingleExtrap,0);
 
}


// 保存反射率高于55dBZ的区域
void CShapeExtend::GetHighValue(Mat Mat2P)
{
 MatHigh.create(Mat2P.rows,Mat2P.cols,CV_8UC3);
 for (int Row=0;Row<Mat2P.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<Mat2P.cols;++Col)
  { 
   Point2i dot(Col,Row);
   int value=GetReflectionValue(Mat2P.at<Vec3b>(dot));
   if (value>55)//反射率在55以上的保留,其余置成黑色
   {
    MatHigh.at<Vec3b>(dot)=Mat2P.at<Vec3b>(dot);
   }
   else MatHigh.at<Vec3b>(dot)=RefBlack;
  }
 }
}


// 得到上分层时刻每层的Mat
void CShapeExtend::GetLastMat(Mat LastMat)
{
 Filter(LastMat);
 GetLayer(LastMat);
 LastMat25.create(LastMat.rows,LastMat.cols,CV_8UC3);//创建并保存上一时刻每层Mat图层
 LastMat30.create(LastMat.rows,LastMat.cols,CV_8UC3);
 LastMat35.create(LastMat.rows,LastMat.cols,CV_8UC3);
 LastMat40.create(LastMat.rows,LastMat.cols,CV_8UC3);
 LastMat45.create(LastMat.rows,LastMat.cols,CV_8UC3);
 LastMat50.create(LastMat.rows,LastMat.cols,CV_8UC3);
 LastMat55.create(LastMat.rows,LastMat.cols,CV_8UC3);
 MatCopy(Mat25,LastMat25,1);
 MatCopy(Mat30,LastMat30,1);
 MatCopy(Mat35,LastMat35,1);
 MatCopy(Mat40,LastMat40,1);
 MatCopy(Mat45,LastMat45,1);
 MatCopy(Mat50,LastMat50,1);
 MatCopy(Mat55,LastMat55,1);
}


// 所有层阈值化
void CShapeExtend::ThresAllMat(void)
{
 ThresMat25.create(Mat25.rows,Mat25.cols,CV_8UC1);
 ThresMat30.create(Mat25.rows,Mat25.cols,CV_8UC1);
 ThresMat35.create(Mat25.rows,Mat25.cols,CV_8UC1);
 ThresMat40.create(Mat25.rows,Mat25.cols,CV_8UC1);
 ThresMat45.create(Mat25.rows,Mat25.cols,CV_8UC1);
 ThresMat50.create(Mat25.rows,Mat25.cols,CV_8UC1);
 ThresMat55.create(Mat25.rows,Mat25.cols,CV_8UC1);

 Threshold(Mat25,ThresMat25);          
 Threshold(Mat30,ThresMat30);
 Threshold(Mat35,ThresMat35);
 Threshold(Mat40,ThresMat40);
 Threshold(Mat45,ThresMat45);
 Threshold(Mat50,ThresMat50);
 Threshold(Mat55,ThresMat55);
 //====================上一时刻所有层阈值化====================
 LastThresMat25.create(LastMat25.rows,LastMat25.cols,CV_8UC1);
 LastThresMat30.create(LastMat25.rows,LastMat25.cols,CV_8UC1);
 LastThresMat35.create(LastMat25.rows,LastMat25.cols,CV_8UC1);
 LastThresMat40.create(LastMat25.rows,LastMat25.cols,CV_8UC1);
 LastThresMat45.create(LastMat25.rows,LastMat25.cols,CV_8UC1);
 LastThresMat50.create(LastMat25.rows,LastMat25.cols,CV_8UC1);
 LastThresMat55.create(LastMat25.rows,LastMat25.cols,CV_8UC1);

 Threshold(LastMat25,LastThresMat25);     
 Threshold(LastMat30,LastThresMat30);
 Threshold(LastMat35,LastThresMat35);
 Threshold(LastMat40,LastThresMat40);
 Threshold(LastMat45,LastThresMat45);
 Threshold(LastMat50,LastThresMat50);
 Threshold(LastMat55,LastThresMat55);
}


// 输入两幅连续时刻彩色MAT 外推结果保存在ExtrapMat3
void CShapeExtend::Extrapolate(Mat LastMat, Mat CurrentMat)
{
 GetLastMat(LastMat);//得到上时刻个图层
 GetHighValue(CurrentMat);//保存当前时刻高于55DBz的部分
 Filter(CurrentMat);
 GetLayer(CurrentMat);//得到当前时刻个图层
    ThresAllMat();//所有图层进行阈值化
 //Mat ExtrapFix;//储存每一层外推修正图
 //ExtrapFix.create(LastThresMat25.rows,LastThresMat25.cols,CV_8UC1);
 //Mat ExtrapMat3;    // 储存每一层外推修正图叠加图                     
 
 vector<Mat> LastThresMatLayer;  //定义Mat容器存放7层Mat图层
 LastThresMatLayer.clear();
 LastThresMatLayer.push_back(LastThresMat55); //把上一时刻7个二值Mat图层压入容器
 LastThresMatLayer.push_back(LastThresMat50);
 LastThresMatLayer.push_back(LastThresMat45);
 LastThresMatLayer.push_back(LastThresMat40);
 LastThresMatLayer.push_back(LastThresMat35);
 LastThresMatLayer.push_back(LastThresMat30);
 LastThresMatLayer.push_back(LastThresMat25);
 vector<Mat>::iterator ite_lastthresmat;//指向上一时刻二值Mat容器的迭代器

 vector<Mat> ThresMatLayer;  //定义Mat容器存放7层Mat图层
 ThresMatLayer.clear();
 ThresMatLayer.push_back(ThresMat55); //把当前时刻7个二值Mat图层压入容器
 ThresMatLayer.push_back(ThresMat50);
 ThresMatLayer.push_back(ThresMat45);
 ThresMatLayer.push_back(ThresMat40);
 ThresMatLayer.push_back(ThresMat35);
 ThresMatLayer.push_back(ThresMat30);
 ThresMatLayer.push_back(ThresMat25);
 vector<Mat>::iterator ite_thresmat;//指向当前时刻二值Mat容器的迭代器
 ite_thresmat= ThresMatLayer.begin();
 ite_lastthresmat= LastThresMatLayer.begin();
 int ref_color=60;

 /*GetRect(LastThresMat25);
 Point2i LastCenDot=rectcenter;
 GetRect(ThresMat25);
 Point2i CurrentCenDot=rectcenter;
 vecx=CurrentCenDot.x-LastCenDot.x;
 vecy=LastCenDot.y-LastCenDot.y;*/
 Mat ExtrapMat1;//储存每一层外推图
 ExtrapMat1.create(LastMat.rows,LastMat.cols,CV_8UC1);
 ExtrapMat3.create(LastMat.rows,LastMat.cols,CV_8UC3);
 ExtrapMat3.setTo(0);
 for (ite_lastthresmat= LastThresMatLayer.begin();ite_lastthresmat!= LastThresMatLayer.end();ite_lastthresmat++,ite_thresmat++)

 {

  GetSingleExtrap(*ite_lastthresmat, *ite_thresmat,  ExtrapMat1);//实现单层图的外推
  //  ========================  二值单层外推图叠加成彩色外推结果=====================


  ref_color-=5;
  for (int Row=0;Row<ExtrapMat1.rows;++Row)//开始遍历图像
  {
   for (int Col=0;Col<ExtrapMat1.cols;++Col)
   {
    Point2i dot(Col,Row);
    if( ExtrapMat1.at<BYTE>(dot)==255&&ExtrapMat3.at<Vec3b>(dot)==RefBlack)
    {
     ExtrapMat3.at<Vec3b>(dot)=ReflectionValue(ref_color);//如果高反射率区域在低反射区域内部,正常叠加
    }
    if( ExtrapMat1.at<BYTE>(dot)==0&&ExtrapMat3.at<Vec3b>(dot)!=RefBlack)
    {
     ExtrapMat3.at<Vec3b>(dot)=ReflectionValue(ref_color);//如果低反射率区域叠加时未能包括高反射率区域,把未包括的区域置成低反射率区域
    }
    //else ExtrapMat3.at<Vec3b>(dot)=RefBlack;
   }
  }
 }
 //======高反射率区域坐标修正==========================
 //Mat MatHighFix;//储存大于55高反射率修正图
 //MatHighFix.create(MatHigh.rows,MatHigh.cols,CV_8UC3);
 //MatHighFix.setTo(0);
 //for (int Row=0;Row<MatHigh.rows;++Row)//开始遍历图像
 //{
 // for (int Col=0;Col<MatHigh.cols;++Col)
 // { 
 //  Point2i dot(Col,Row);
 //  Point2i dotfix(Col+vecx,Row+vecy);
 //  if(MatHigh.at<Vec3b>(dot)!=RefBlack)
 //   MatHighFix.at<Vec3b>(dotfix)=MatHigh.at<Vec3b>(dot);
 // }
 //}
 //===================高反射率区域覆盖===============
 for (int Row=0;Row<MatHigh.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<MatHigh.cols;++Col)
  {
   Point2i dot(Col,Row);
   if( MatHigh.at<Vec3b>(dot)!=RefBlack)
   {
    ExtrapMat3.at<Vec3b>(dot)=MatHigh.at<Vec3b>(dot);//高于55高反射率区域叠加
   }
  }
 }
 //IplImage iplExtrapMat3 =ExtrapMat3;
 //cvSaveImage("C:\\外推\\下一时刻外推图.bmp",&iplExtrapMat3);
 //cv::namedWindow("外推的图片",CV_WINDOW_AUTOSIZE);
 //cv::imshow("外推的图片",ExtrapMat3);
}


void CShapeExtend::GetCellRect(Mat src,CvRect Rect)//选中图的rect存储到Curcell中
{
 crtcellorgpt.x=Rect.x;      //记录当前选中单体矩形区域的起始点
 crtcellorgpt.y=Rect.y;

 Curcell.create(Rect.height,Rect.width,CV_8UC3);
 for (int Row=0;Row<Curcell.rows;Row++)
 {
  for (int Col=0;Col<Curcell.cols;Col++)
  {
   Point2i poi(Col,Row);
   Point2i poi2(Col+crtcellorgpt.x,Row+crtcellorgpt.y);
   Curcell.at<Vec3b>(poi)=src.at<Vec3b>(poi2);
  }
 }
 /*temp=IplImage(Matcell);
 cv::namedWindow("单体的图片",CV_WINDOW_AUTOSIZE);
 cv::imshow("单体的图片",Matcell);*/
}
void CShapeExtend::GetLastCellRect(Mat src)
{
 Lstcell.create(Curcell.rows,Curcell.cols,CV_8UC3);
 for (int Row=0;Row<Lstcell.rows;Row++)
 {
  for (int Col=0;Col<Lstcell.cols;Col++)
  {
   Point2i poi(Col,Row);
   Point2i poi2(Col+lstcellorgpt.x,Row+lstcellorgpt.y);
   Lstcell.at<Vec3b>(poi)=src.at<Vec3b>(poi2);
  }
 }
}


void CShapeExtend::Gray(Mat Src, IplImage* Dst)
{
 IplImage src= IplImage(Src);
 IplImage *singlesrc2;
 //Dst=cvCreateImage(cvGetSize(&src),32,1);
 singlesrc2=cvCreateImage(cvGetSize(&src),32,3);
 cvConvertScale(&src,singlesrc2,1.0/255.0,0);//源图像转化为浮点数图形,准备灰度化
 cvCvtColor(singlesrc2,Dst,CV_BGR2GRAY);//源图像转化为单通道灰度图像
}


void CShapeExtend::Match(IplImage* src, IplImage* temp)
{

 IplImage *floatsrc;                                //浮点数图像转化
 floatsrc=cvCreateImage(cvGetSize(src),32,1);
 IplImage *floattemp;
 floattemp=cvCreateImage(cvGetSize(temp),32,1);
 cvConvertScale(src,floatsrc,1.0/255.0,0);
 cvConvertScale(temp,floattemp,1.0/255.0,0);

 int iwidth=src->width-temp->width+1;
 int iheight=src->height-temp->height+1;
 IplImage *ftmp;                              //存放cvMatchTemplate的输出矩阵
 ftmp=cvCreateImage(cvSize(iwidth,iheight),32,1);
 cvMatchTemplate(floatsrc,floattemp,ftmp,CV_TM_CCOEFF_NORMED);
 CvPoint maxpt=cvPoint(0,0);       
 cvMinMaxLoc(ftmp,NULL,NULL,NULL,&maxpt);
 lstcellorgpt=maxpt;
 cvNamedWindow("Ccoeff_Normed",0);
 cvShowImage("Ccoeff_Normed",ftmp);    //显示匹配结果矩阵,maxpoint记录了最大相关点
}

 


// 将源图像中反射率大于40DBz的像素保存并且提取边缘存储到点容器中
void CShapeExtend::Get2Dpoints(Mat src, Point inipt)
{
 Mat Tempcrtcell;//
 Tempcrtcell.create(src.rows,src.cols,CV_8UC3);
 Mat Tempcrtcell2;//
 Tempcrtcell2.create(src.rows,src.cols,CV_8UC1);
 for (int Row=0;Row<src.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<src.cols;++Col)
  { 
   Point2i dot(Col,Row);
   int value=GetReflectionValue(src.at<Vec3b>(dot));
   if (value<40)//反射率在40以下的置成黑色
   {
    Tempcrtcell.at<Vec3b>(dot)=RefBlack;
   }
   else Tempcrtcell.at<Vec3b>(dot)=src.at<Vec3b>(dot);
  }
 }
 Threshold(Tempcrtcell,Tempcrtcell2);
 //cv::namedWindow("单体过滤",CV_WINDOW_AUTOSIZE);
 //cv::imshow("单体过滤",Tempcrtcell2);
//=========================================================================
 PointsVector.clear();
 vector<vector<Point>> cell_contours;//存储连通区域
 vector<vector<Point>>::iterator ite_contours;//指向vector<Point>容器的迭代器
 vector<Point>::iterator ite_points;//指向Point容器的迭代器
 cv::findContours(Tempcrtcell2,cell_contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);//只检测外轮廓,存储所有的轮廓点,相邻的两个点的像素位置差不超过1
 Point temp;
 double s=0;
 for (ite_contours= cell_contours.begin();ite_contours!= cell_contours.end();ite_contours++)
 {
  if(contourArea(Mat(*ite_contours))>s)
  {
   s=contourArea(Mat(*ite_contours));
   PointsVector.clear();
   for(ite_points=(*ite_contours).begin();ite_points!=(*ite_contours).end();ite_points++)
   {
    temp.x=(*ite_points).x+inipt.x;
    temp.y=(*ite_points).y+inipt.y;
    PointsVector.push_back(temp);
   }
  }
 }
}


// 将点集p_Vec的最小外包矩形存入Box中,并将矩形绘制在dst中
void CShapeExtend::GetCvBox(vector<Point> p_Vec, Mat dst)
{
 //======================点容器转化为二维点集================================

 CvPoint2D32f tempNode;
 CvMemStorage* storage = cvCreateMemStorage(0);
 CvSeq* pointSeq = cvCreateSeq(CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), storage);
 for (int i = 0; i < p_Vec.size(); i++)
 {//添加点 
  tempNode.x = p_Vec.at(i).x; 
  tempNode.y = p_Vec.at(i).y; 
  cvSeqPush(pointSeq, &tempNode);
 }

 //================找出最小二乘拟合椭圆==============================================
 Box=cvFitEllipse2(pointSeq);
 //rect=Box;

 IplImage pImg= IplImage(dst);
 cvEllipseBox(&pImg,Box,CV_RGB(255,255,255));
 //=============找出完整包含轮廓的最小矩形=====================
 //rect = cvMinAreaRect2(pointSeq);
 ////用cvBoxPoints找出矩形的4个顶点
 //CvPoint2D32f rect_pts0[4];
 //cvBoxPoints(rect, rect_pts0);
 ////因为cvPolyLine要求点集的输入类型是CvPoint**
 ////所以要把 CvPoint2D32f 型的 rect_pts0 转换为 CvPoint 型的 rect_pts
 ////并赋予一个对应的指针 *pt
 //int npts = 4;
 //CvPoint rect_pts[4], *pt = rect_pts;
 //for (int rp=0; rp<4; rp++)
 // rect_pts[rp]= cvPointFrom32f(rect_pts0[rp]);
 ////画出Box
 //IplImage pImg= IplImage(dst);
 //cvPolyLine(&pImg, &pt, &npts, 1, 1, CV_RGB(255,0,0), 2);
}


// 过滤低反射率区域
void CShapeExtend::Filterlow(Mat Mat2Flt)
{
 for (int Row=0;Row<Mat2Flt.rows;++Row)//开始遍历图像
 {
  for (int Col=0;Col<Mat2Flt.cols;++Col)
  { 
   Point2i dot(Col,Row);
   int value=GetReflectionValue(Mat2Flt.at<Vec3b>(dot));
   if (value<25)//反射率在25以下的置成黑色
   {
    Mat2Flt.at<Vec3b>(dot)=RefBlack;
   }
  }
 }
}


void CShapeExtend::Rotate(Mat srcMat, Mat dstMat, Point center, double angle)
{
 double rx0=center.x;  //(rx0,ry0)为旋转中心
 double ry0=center.y;
 double degree=0;
 if (angle<=5&&angle>=-5)
 {
  degree = angle;
 }
 double RotaryAngle= degree * CV_PI / 180.;
 for (long x=0;x<srcMat.cols;++x)
 {
  for (long y=0;y<srcMat.rows;++y)
  {
   long dstx=(long)((x - rx0)*cos(RotaryAngle) + (y - ry0)*sin(RotaryAngle) + rx0) ;
   long dsty=(long)(-(x - rx0)*sin(RotaryAngle) + (y - ry0)*cos(RotaryAngle) + ry0 ) ;
   if ( (dstx>=0)&&(dstx<srcMat.cols) && (dsty>=0)&&(dsty<srcMat.rows) )
    dstMat.at<Vec3b>(dstx,dsty)=srcMat.at<Vec3b>(x,y);
  }
 }
}


void CShapeExtend::GetRealRect(Mat src, Mat temp, Mat rect)
{
 IplImage *singlesrc;
 singlesrc=cvCreateImage(cvGetSize(&IplImage(src)),32,1);
 Gray(src,singlesrc);   //matofnext灰度化保存到singlesrc中
 IplImage *singletemp;
 singletemp=cvCreateImage(cvGetSize(&IplImage(temp)),32,1);
 Gray(temp,singletemp);
 
 
 IplImage *floatsrc;                                //浮点数图像转化
 floatsrc=cvCreateImage(cvGetSize(singlesrc),32,1);
 IplImage *floattemp;
 floattemp=cvCreateImage(cvGetSize(singletemp),32,1);
 cvConvertScale(singlesrc,floatsrc,1.0/255.0,0);
 cvConvertScale(singletemp,floattemp,1.0/255.0,0);

 int iwidth=singlesrc->width-singletemp->width+1;
 int iheight=singlesrc->height-singletemp->height+1;
 IplImage *ftmp;                              //存放cvMatchTemplate的输出矩阵
 ftmp=cvCreateImage(cvSize(iwidth,iheight),32,1);
 cvMatchTemplate(floatsrc,floattemp,ftmp,CV_TM_CCOEFF_NORMED);
 CvPoint maxpt=cvPoint(0,0);
 double max_val=0;
 cvMinMaxLoc(ftmp,NULL,&max_val,NULL,&maxpt);
 nextrealorpt=maxpt;
 //cvNamedWindow("Ccoeff_Normed",0);
 //cvShowImage("Ccoeff_Normed",ftmp);
 ccoeff=max_val;
 for (int Row=0;Row<rect.rows;Row++)
 {
  for (int Col=0;Col<rect.cols;Col++)
  {
   Point2i poi(Col,Row);
   Point2i poi2(Col+nextrealorpt.x,Row+nextrealorpt.y);
   rect.at<Vec3b>(poi)=src.at<Vec3b>(poi2);
  }
 }
}

你可能感兴趣的:(图像外推算法)