#include "stdafx.h"
#include <opencv2\opencv.hpp>
#include <iostream>
#include <stack>
using namespace cv;
using namespace std;
double _ptolinesegdist(int x0,int y0,int x1,int y1,int x2,int y2);
//起点生长
void findline(Mat& MatIn,int growstartx,int growstarty ,vector<Point>& ptsclosed)//iGrowPoint为种子点的判断条件,iGrowJudge为生长条件
{
//初始化原始种子点
int DIR[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
//int iJudge=countNonZero(MatTemp);
vector<Point> seeds;
seeds.push_back(Point(growstartx,growstarty));
Point curgrow;
//ptsclosed.clear();
ptsclosed.push_back(Point(growstartx,growstarty));
MatIn.at<uchar>(growstartx,growstarty)=0;
while(!seeds.empty())
{
curgrow=seeds.back();
seeds.pop_back();
int i=curgrow.x;
int j=curgrow.y; ;
for(int iNum=0;iNum<8;iNum++)
{
int iCurPosX=i+DIR[iNum][0];
int iCurPosY=j+DIR[iNum][1];
if(iCurPosX>=0 && iCurPosX<=(MatIn.rows-1) && iCurPosY>=0 && iCurPosY<=(MatIn.cols-1))
{
if(MatIn.at<uchar>(iCurPosX,iCurPosY)==255 )//生长条件,自己调整
{
seeds.push_back(Point(iCurPosX,iCurPosY));
ptsclosed.push_back(Point(iCurPosX,iCurPosY));
MatIn.at<uchar>(iCurPosX,iCurPosY)=0;
//break;
}
}
}
}
}
void findlines(Mat& MatIn, vector<vector<Point>>& ptsclosed,int minpts)
{
for(int i=0;i<MatIn.rows;i++)
{
for(int j=0;j<MatIn.cols;j++)
{
if(MatIn.at<uchar>(i,j)==255 )
{
vector<Point> pts;
findline(MatIn,i,j,pts);
if(pts.size()>=minpts)
{
ptsclosed.push_back(pts);
}
}
}
}
}
//统计核内的高亮点
int neighbourpoints(Mat &MatIn,int x,int y,int kernel)
{
int brights=0;
for(int i=0-kernel;i<=kernel;i++)
{
for(int j=0-kernel;j<=kernel;j++)
{
int iCurPosX=i+x;
int iCurPosY=j+y;
if(iCurPosX<=0 ||iCurPosX>=(MatIn.rows-1)|| iCurPosY<=0 || iCurPosY>=(MatIn.cols-1)) continue;
if(MatIn.at<uchar>(iCurPosX,iCurPosY)==255)brights++;
}
}
return brights;
}
int neighbourpointsInRect(Mat &MatIn,int x,int y,int x1,int y1)
{
int brights=0;
for(int i=x;(x<x1)?i<=x1:i>=x1;(x<x1)?i++:i--)
{
for(int j=y;(y<y1)?j<=y1:j>=y1;(y<y1)?j++:j--)
{
if(MatIn.at<uchar>(i,j)==255)brights++;
}
}
return brights;
}
void neighbourpointsInRect2(Mat &MatIn,int x,int y,int x1,int y1,vector<Point>&pts)
{
for(int i=x;(x<x1)?i<=x1:i>=x1;(x<x1)?i++:i--)
{
for(int j=y;(y<y1)?j<=y1:j>=y1;(y<y1)?j++:j--)
{
if(MatIn.at<uchar>(i,j)==255){
pts.push_back(Point(i,j));
}
}
}
}
int ptInptv(vector<Point>&ptv,int x,int y)
{
if(ptv.size()==0)return 0;
for(int i=0;i<ptv.size();i++){
if(ptv[i].x==x&&ptv[i].y==y)return 1;
}
return 0;
}
int ptInptvv(vector<vector<Point>>&ptvv,int x,int y)
{
if(ptvv.size()==0)return 0;
for(int i=0;i<ptvv.size();i++){
if(ptInptv(ptvv[i],x,y))return 1;
}
return 0;
}
int isConnectedBetween2Points(Mat &MatIn,int x,int y,int x1,int y1)
{
if(x==x1||y==y1){
for(int i=x;x<x1?i<=x1:i>=x1;x<x1?i++:i--){
for(int j=y;y<y1?j<=y1:j>=y1;y<y1?j++:j--){
if(MatIn.at<uchar>(i,j)!=255)return 0;
}
}
return 1;
}
int minx,miny;
int maxx,maxy;
minx=min(x,x1);
miny=min(y,y1);
maxx=max(x,x1);
maxy=max(y,y1);
Rect rc(miny,minx,maxy-miny+1,maxx-minx+1);
//PrintMat2(MatIn,minx,miny,maxx-minx+1,maxy-miny+1);
Mat subMat=MatIn(rc);
//PrintMat(subMat);
/*vector<Point> pts;
findline(subMat.clone(),x-minx,y-miny,pts);
if(pts.size()>=2)
{
if(ptInptv(pts,x-minx,y-miny)&&ptInptv(pts,x1-minx,y1-miny))return 1;
}*/
#if 0
vector<vector<Point>> ptsclosed;
findlines( subMat.clone(), ptsclosed,2);
//AfxMessageBox("");exit(0);
if(ptInptvv(ptsclosed,x-minx,y-miny)&&ptInptvv(ptsclosed,x1-minx,y1-miny))
{
return 1;
}
#else
vector<Point> ptsclosed;
findline( subMat.clone(),x-minx,y-miny, ptsclosed);
//AfxMessageBox("");exit(0);
if(ptInptv(ptsclosed,x1-minx,y1-miny))
{
return 1;
}
#endif
return 0;
}
void _selectshortpath( vector<Point>& pts,int x,int y, int x1,int y1)
{
//minx,miny------>minx,maxy---->maxx,maxy
if(isnibpt(Point(x,y),Point(x1,y1))){
pts.push_back(Point(x,y));
pts.push_back(Point(x1,y1));
return;
}
for(int i =x;(x<x1)?(i<=x1):(i>=x1);(x<x1)?(i++):(i--)){
pts.push_back(Point(i,y));
}
for(int i =y;(y<y1)?(i<=y1):(i>=y1);(y<y1)?(i++):(i--)){
pts.push_back(Point(x1,i));
}
}
int ptsinptnib(Mat& MatIn,int x,int y,uchar v)
{
int DIR[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int tot=0;
for(int iNum=0;iNum<8;iNum++)
{
int iCurPosX= x+DIR[iNum][0];
int iCurPosY= y+DIR[iNum][1];
if(iCurPosX>=0 && iCurPosX<=(MatIn.rows-1) && iCurPosY>=0 && iCurPosY<=(MatIn.cols-1))
{
if(MatIn.at<uchar>(iCurPosX,iCurPosY)==v )//生长条件,自己调整
{
tot++;
}
}
}
return tot;
}
int selectshortpath(Mat& MatIn,vector<Point>& pts,int x,int y, int x1,int y1,int iGroweasy)
{
//minx,miny------>minx,maxy---->maxx,maxy
if(iGroweasy){
vector<Point>ptshighlight;
neighbourpointsInRect2(MatIn,x,y,x1,y1,ptshighlight);
for(int i=0;i<ptshighlight.size()-1;i++){
_selectshortpath(pts,ptshighlight[i].x,ptshighlight[i].y,ptshighlight[i+1].x,ptshighlight[i+1].y);
}
return 1;
}
int minx,miny;
int maxx,maxy;
minx=min(x,x1);
miny=min(y,y1);
maxx=max(x,x1);
maxy=max(y,y1);
Rect rc(miny,minx,maxy-miny+1,maxx-minx+1);
//PrintMat2(MatIn,minx,miny,maxx-minx+1,maxy-miny+1);
Mat subMat=MatIn(rc).clone();
typedef struct _pointorder{
int x;
int y;
int order;
_pointorder(int a,int b,int c){
x=a;
y=b;
order=c;
};
_pointorder(){
};
}PTO;
vector<vector<PTO>> lines;
vector<PTO>pathpts;
PTO ptnow;
int DIR[8][2]={/*{-1,-1},{-1,0},{-1,1},{0,-1},*/{0,1},/*{1,-1},*/{1,0},{1,1}};
pathpts.push_back(PTO(x-minx,y-miny,0));
int flagx=x1>x?1:-1;
int flagy=y1>y?1:-1;
while(pathpts.size())
{
_do1:
ptnow=pathpts.back();
for(int iNum=ptnow.order;iNum<3;iNum++)
{
int iCurPosX=ptnow.x+DIR[iNum][0]*flagx;
int iCurPosY=ptnow.y+DIR[iNum][1]*flagy;
if(iCurPosX>=0 && iCurPosX<=(subMat.rows-1) && iCurPosY>=0 && iCurPosY<=(subMat.cols-1))
{
if(iCurPosX==x1-minx&&iCurPosY==y1-miny)
{
lines.push_back(pathpts);
goto _do2;
}
else if(subMat.at<uchar>(iCurPosX,iCurPosY)==0 )//生长条件,自己调整
{
pathpts.push_back(PTO(iCurPosX,iCurPosY,0));
goto _do1;
/* break;*/
}
}
}
_do2:
pathpts.pop_back();
if(pathpts.size()){
ptnow=pathpts.back();
pathpts.pop_back();
ptnow.order++;
pathpts.push_back(ptnow);
}
}
if(lines.size()==0)return 0;
int smalllength=BIGINT;
int smallindex=0;
for(int i=0;i<lines.size();i++){
if(smalllength>lines[i].size()){
smalllength=lines[i].size();
smallindex=i;
}
}
for(int i=0;i<lines[smallindex].size();i++){
pts.push_back(Point(lines[smallindex][i].x+minx,lines[smallindex][i].y+miny));
}
return 1;
/*for(int i=0;i<subMat.rows;i++){
for(int j=0;j<subMat.cols;j++){
}
}*/
//findlines(subMat.clone(),ptss,2);
//if(ptss.size()){
// for(int i=0;i<ptss.size();i++){
// if(ptInptv(ptss[i],x-minx,y-miny)&&ptInptv(ptss[i],x1-minx,y1-miny))return ;
// }
//}
//_selectshortpath( pts, x, y, x1, y1);
}
//获取mat的指定亮度点的个数 灰度图
void getmatvaluepts(Mat&src_gray,vector<Point>&pts,int v)
{
for(int i=0;i<src_gray.rows;i++){
for(int j=0;j<src_gray.cols;j++){
if(src_gray.at<uchar>(i,j)==v){
pts.push_back(Point(i,j));
}
}
}
}
//获取浮点mat的极值点,x,y
void getShortMatPeakPts(Mat&src_gray,vector<Point>&pts,bool x,bool checkdouble)
{
if(x){
for(int i=0;i<src_gray.rows;i++){
for(int j=1;j<src_gray.cols-1;j++){
if((src_gray.at<short>(i,j-1)>0&&src_gray.at<short>(i,j+1)<0)
||(src_gray.at<short>(i,j-1)<0&&src_gray.at<short>(i,j+1)>0))
{
if(checkdouble){
int findsameed=0;
for(int k=0;k<pts.size();k++){
if(pts[i].x==i&&pts[i].y==j){
findsameed=1;
break;
}
}
if(findsameed)continue;
}
pts.push_back(Point(i,j));
}
}
}
}else{
for(int i=0;i<src_gray.cols;i++){
for(int j=1;j<src_gray.rows-1;j++){
if((src_gray.at<short>(j-1,i)>0&&src_gray.at<short>(j+1,j )<0)
||(src_gray.at<short>(j-1,i)<0&&src_gray.at<short>(j+1,j)>0))
{
if(checkdouble){
int findsameed=0;
for(int k=0;k<pts.size();k++){
if(pts[i].x==i&&pts[i].y==j){
findsameed=1;
break;
}
}
if(findsameed)continue;
}
pts.push_back(Point(j,i));
}
}
}
}
}
//获取矩阵的极值点 灰度图
void getMatSecondDerivativeExtreme(Mat&src_gray,vector<Point>&ptspeak)
{
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
/// Generate grad_x and grad_y
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
/// Gradient X
//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
getShortMatPeakPts( grad_x, ptspeak,1 ,0);
/// Gradient Y
//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
getShortMatPeakPts ( grad_y, ptspeak,0,1 );
}
//全图曲线生长
Mat fullCurseGrow(Mat& MatIn, int kernel,int iGroweasy,int lowptsinline)
{
vector<Point>ptspeak;
getMatSecondDerivativeExtreme(MatIn,ptspeak);
vector<vector<Point>> ptvv;
findlines(MatIn.clone(),ptvv,lowptsinline);
Mat m=MatIn.clone();
for(int i=0;i<ptspeak.size();i++){
if(ptInptvv(ptvv,ptspeak[i].x,ptspeak[i].y)){
m=curseGrow(m,ptspeak[i].x,ptspeak[i].y,kernel,iGroweasy,1);
}
}
return m;
}
//曲线k延伸,如果最近k距离点有亮点,就延伸过去
Mat curseGrow(Mat& MatIn,int growstartx,int growstarty ,int kernel,bool iGroweasy,bool smallfirstflag)
{
Mat Matnow=MatIn.clone();//(MatIn.size(),CV_8UC1,Scalar(0));
vector<Point> seeds;
seeds.push_back(Point(growstartx,growstarty));
Point curgrow;
while(!seeds.empty()){
curgrow=seeds.back();
seeds.pop_back();
Matnow.at<uchar>(curgrow.x,curgrow.y)=255;
/*if(neighbourpoints(MatIn,curgrow.x,curgrow.y,kernel)>=kernel*2+1){
continue;
}*/
vector<Point> brightptsforign;
for(int i=0-kernel-1;i<=kernel+1;i++){
for(int j=0-kernel-1;j<=kernel+1;j++){
int iCurPosX=i+curgrow.x;
int iCurPosY=curgrow.y+j;
if(iCurPosX<=0 ||iCurPosX>=(MatIn.rows-1)|| iCurPosY<=0 || iCurPosY>=(MatIn.cols-1)) continue;
if(i==0&&j==0)continue;
if(Matnow.at<uchar>(iCurPosX,iCurPosY)==255)
brightptsforign.push_back(Point(iCurPosX,iCurPosY));
}
}
// for(int i=-kernel-1;i<=kernel+1;i+=(kernel+1)*2){
// for(int j= -kernel;j<=kernel;j++){
// int iCurPosX=i+curgrow.x;
// int iCurPosY=curgrow.y+j;
// if(iCurPosX<0 ||iCurPosX>(MatIn.rows-1)|| iCurPosY<0 || iCurPosY>(MatIn.cols-1)) continue;
// if(Matnow.at<uchar>(iCurPosX,iCurPosY)==255)
// brightptsforign.push_back(Point(iCurPosX,iCurPosY));
// }
//}
int smalldistance=smallfirstflag*BIGINT;
Point goodpt;
for(int i=0;i<brightptsforign.size();i++)
{
if(!isConnectedBetween2Points(Matnow,brightptsforign[i].x,brightptsforign[i].y,curgrow.x,curgrow.y))
{
int distance=(brightptsforign[i].x-curgrow.x)*(brightptsforign[i].x-curgrow.x)+(brightptsforign[i].y-curgrow.y)*(brightptsforign[i].y-curgrow.y);
if((smallfirstflag&&distance<smalldistance)||(!smallfirstflag&&distance>smalldistance)){
smalldistance=distance;
goodpt=brightptsforign[i];
}
/* Matnow.at<uchar>(brightptsforign[i].x,brightptsforign[i].y)=255;
vector<Point> goodpath;
selectshortpath(Matnow,goodpath,curgrow.x,curgrow.y,brightptsforign[i].x,brightptsforign[i].y);
for(int i=0;i<goodpath.size();i++){
Matnow.at<uchar>(goodpath[i].x,goodpath[i].y)=255;
}
seeds.push_back(Point(brightptsforign[i].x,brightptsforign[i].y));*/
//break;
}
}
if(smalldistance!=smallfirstflag*BIGINT){
Matnow.at<uchar>(goodpt.x,goodpt.y)=255;
vector<Point> goodpath;
if(selectshortpath(Matnow,goodpath,curgrow.x,curgrow.y,goodpt.x,goodpt.y,iGroweasy))
{
for(int i=0;i<goodpath.size();i++)
{
Matnow.at<uchar>(goodpath[i].x,goodpath[i].y)=255;
}
seeds.push_back(Point(goodpt.x,goodpt.y));
}
}
}
return Matnow;
}
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h> // MFC support for ribbons and control bars
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
#include <stdarg.h>
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
typedef int (*CALLBACK_T)(const char* file,void * p);
int stepDirFileNoRecurse(CString& strDir,CALLBACK_T fncallback,void* p);
void fprint(const char* format,...);
void flog(const char* fmt,...);
CString gettimestring( );
void sortrc(vector<Rect>& boundRect ,vector<Rect>& res,int bigfirst=1);
void combinenibrcs(vector<Rect>& boundRect ,vector<Rect>& res);
int isnibrc(Rect&rc0,Rect&rc1);
void combinenibrc(Rect&rc0,Rect&rc1,Rect& rcnew);
int iscorrectcharrcs(vector<Rect>& boundRect,vector<Rect>&rcsorder);
int getmaxcontinuecharrcs(vector<Rect>& boundRectorder,vector<Rect>&continuercs);
void savecontour(Mat& img,vector<Rect>&boundrc,const char*fname,vector<Mat>&mats);
void findcontourslog(Mat &img,const char* filepath,int ind,vector<Mat>&mats);
int main_test(const char* fileimage, float f,float s,int ind,vector<Mat>&mats);
DWORD WINAPI knn_simple_test2(void*p);
void knn_train(Mat& traindata, Mat& trainlabel, int k);
int knn_predict(Mat& testdata,int k );
void enhenceimg(Mat &img,Mat &imageEnhance,float r);
int gammaenhence(Mat &image,Mat& gray_Contrast,float r) ;
void z2(Mat &img,Mat &b2);
int sobelxy( Mat&src_gray,Mat&grad );
void BoundarySeedFill(Mat &src, Point ptStart) ;
Mat otsu(Mat& img);
void findLines(Mat &_inputimg, vector<deque<Point>> &_outputlines);
Scalar random_color(RNG& _rng);
bool isnibpt(Point&p1,Point& p2);
Mat RegionGrow(Mat MatIn,int iGrowPoint,int iGrowJudge);
Mat RegionGrowSeed(Mat src, Point2i pt, int th) ;
void getmingraybygrad(Mat& old,Mat&sob,uchar minth,vector<Point>& pts);
Mat RegionGrowFromPoint(Mat MatIn,int growstartx,int growstarty ,int iGrowJudge);
Mat curseGrow(Mat& MatIn,int growstartx,int growstarty ,int kernel,bool iGroweasy,bool smallfirstflag);
void findlines(Mat& MatIn, vector<vector<Point>>& ptsclosed,int minpts);
void neighbourpointsInRect2(Mat &MatIn,int x,int y,int x1,int y1,vector<Point>&pts);
#define BIGINT 666666
#define MINDISTCHARINIMG 2
#define MAXDILATESIZEFORREMOVEGOOD 21
#define MINCOUTOURAREA 9
#define MINCOUTOURHEIGHT 5
#define MINCOUTOURWIDTH 5
#define MINCOUTOURRECTAREA 1
int isclosecurse(vector<Point>& pts);
Rect convertrc(Rect rc);
int rectinrect(int x,int y,int w,int h ,int x1,int y1,int w1,int h1);
void getcontoursfrommatrect(Mat& gray,Rect rc,vector<Rect>&boundingrcs);
void drawcontour(Mat& img,vector<Rect>&boundrc);
void getsobelinnerrcsfromgray(Mat & gray,vector<Rect>&rectsAll);
int main_test_sobel(const char* fileimage, float f,float s,int ind,vector<Mat>&mats);
void drawcontour2(Mat& img,vector<Rect>&boundrc,const char* winname);
void getcontours(Mat& m2v, vector<Rect>&boundingrcs);
void getsobelinnerrcsfromgray2(Mat & gray,vector<Rect>&rectsAll);
void getsobelinnerrcsfromgrayinr(Mat & gray,vector<Rect>&rectsAll);
int main_test_inr(const char* fileimage, float f,float s,int ind,vector<Mat>&mats);
int sobel2xy( Mat&src_gray,Mat&grad );
int maxValueHist(Mat& Frame, int downValue,int topvalue);
Mat fullCurseGrow(Mat& MatIn, int kernel,int iGroweasy,int lowptsinline);
完整版本的曲线生长