#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);
}
}
}