三维测量

DetectCodePoint.h

#ifndef DetectCodedPoint_H
#define DetectCodedPoint_H

#include "cv.h"
#include "highgui.h"
#include <vector>
#include <atlstr.h>
#include <stdio.h>
#include <string.h>


using namespace std;
using namespace cv;


//****************************************
//定义一用于存储可能的编码信息,包括中心点坐标\椭圆率\椭圆的半长轴

struct  strEllipseInfo 
{
	CvPoint2D32f  p;	//椭圆中心坐标
	float height;		//椭圆的长轴
	float width;		//椭圆的短轴
	float angle;		//椭圆的倾斜角
	float Celiipse;	    //椭圆的圆度值
	float area;			//椭圆的面积
	float perimeter;	//椭圆的周长
	double pointErr;	//拟合椭圆时形成的点距误差
	
	strEllipseInfo()
	{
		p = cvPoint2D32f(0.0,0.0);
		height    = 0.0;
		width     = 0.0;
		angle     = 0.0;
		Celiipse  = 0.0;
		area      = 0.0;
		perimeter = 0.0;
		pointErr  = 0.0;
	}
	strEllipseInfo(CvPoint2D32f point ,float in_height,float in_width,float in_angle,
					float in_Celiipse,float in_area, float in_perimeter, double in_pointErr)
	{
		p = point;
		height    = in_height;
		width     = in_width;
		angle     = in_angle;
		Celiipse  = in_Celiipse;
		area      = in_area;
		perimeter = in_perimeter;
		pointErr  = in_pointErr;
	}

};
//*****************************************************
struct tagPoint 
{
	CvPoint2D32f point;
	int pointgray;
};
//**************************************************************

//**************************************************************
//输出的标记点信息
struct  tagCodeInfo 
{
	double fx;//中心坐标x
	double fy;//中心坐标y;
	int  icodeNumber;//标记圆码值,非零代表编码点的编码值,0代表非编码点
};


class DetectCodePoint
{
public:
	DetectCodePoint (int thresh);
	//~DetectCodePoint();
	void MatrixFromImageGroup(vector<CString>& fileNameList,CString path);
	vector<tagCodeInfo> DetectReferencePointFromImage(CString fileName,CString jieguoname, CString original);
	IplImage* ImagLoad( CString filename );
private:
	int edge_thresh  ;				//canny边缘检测的一个参数,另一个参数是其3倍
	vector<double> areaError;
//**********
//内部操作 *
//**********
protected:
	double Pointangle( CvPoint2D32f pt1, CvPoint2D32f pt2, CvPoint2D32f pt0 );
	void DetectCodePoint::GrayImage(IplImage* source,IplImage* dest);
	IplImage* SmothImage(IplImage* grayimage);
	IplImage* HistImage(IplImage* Gsmothimage);
	IplImage* EdgeImage(IplImage* Hist_Image,int edge_thresh);
	int otsu (IplImage *image,int x0, int y0, int dx, int dy);
	void DetectCodePoint::TwoGrayPlatm( IplImage* gray,IplImage* imageplat);
	vector<strEllipseInfo> process_image(IplImage *edgeimage,IplImage* twogray );
	vector<strEllipseInfo> RemoveFalRefPt(vector<strEllipseInfo>& vector1	);		//去掉不是标记点的
	void departUncode_AND_Code(vector<strEllipseInfo>& vCdatRefPt,
		vector<strEllipseInfo>& vCodePt,
		vector<strEllipseInfo>& vUncodePt,
				IplImage* twogray);
	unsigned short  incoded(strEllipseInfo codebox,IplImage* image, double beishu);
	int min_of_shift(unsigned short codenumber);
	void  TwoGray(IplImage* gray,IplImage* imageplat,IplImage* twogray);
	void ShowNumber(IplImage* image,CvPoint point,int number);
	int GetEdgeThresh(){return edge_thresh;}
	bool CheckWhiteCounter(CvSeq* cont,IplImage *twogray);
	unsigned short  Rol(unsigned short a);
	void DrawRedCross(CvPoint pt,IplImage* image);
	void  Sort (int* pData,int Count); 
	int averGrayofCount(CvSeq* cont,IplImage *twogray,CvPoint center,int radius);
	CvBox2D32f* FitEllipse(CvSeq* cont);
	int   threshEllispe(IplImage* gray ,strEllipseInfo codepoint);
	float threshcirque(IplImage* gray,strEllipseInfo point1);						//求指定图象上一个连同域内象素点个数的总和
};
 	
#endif

DetectCodePoint.cpp

#include "DetectCodedPoint.h"
#include <math.h>
#include <iostream>
#include <fstream>
#include <time.h>

using namespace std ;
using namespace cv;

#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#endif

#define  HDIM 256        //灰度直方图的数组大小


const double PI = (atan(1.0)*4);
const double  dseta=PI/180.0;
#define  arraysize 360;//解码的单位圆的数组大小

/*********************************************
*函数名称:Rol
*函数功能:实现将unsigned short b进行循环左移1位
*返回类型:循环移位后的结果
*最后修改:2017年9月30日 张逸骅
***********************************************/
unsigned short  DetectCodePoint::Rol(unsigned short a)
{
	unsigned short b;
	b=(a<<1)|(a>>15);
	return b;
}



/******************************************************
*DetectCodePoint类构造函数
*******************************************************/
DetectCodePoint::DetectCodePoint(int h)
{
	edge_thresh=h;
}


/*******************************************
*函数名称:ImagLoad
*功能:    读取图片
*返回值:  待测图片
**********************************************/
IplImage*  DetectCodePoint::ImagLoad( CString filename)
{
	IplImage* image=0;
	image=cvLoadImage(filename,-1);//LOAD image
	return image;
}



/*******************************************************************
* 函数名称:IplImage*  GrayImage()
* 函数功能:把任意格式的图形转换成单通道的灰度图
* 输入参数:IplImage* source  --指向圆图形	
* 输出参数:IplImage* gray    --指向转换后的灰度图,必须为8位单通道
* 最后修改:2017年9月30日 张逸骅	  
********************************************************************/
void  DetectCodePoint::GrayImage(IplImage* source,IplImage* dest)
{
		cvCvtColor(source, dest, CV_BGR2GRAY);	
}



/*******************************************************************
* 函数名称:IplImage*  TwoGrayPlatm()
* 函数功能:求取灰度图像上每个像素二值化的灰度阈值
  使用的块的大小为编码标记圆在图象上的大致像素大小160*160
* 输入参数:IplImage* gray   --指向灰度图
* 输出参数:IplImage*     --阈值模板
* 最后修改:2017年9月30日 张逸骅	 
********************************************************************/
void DetectCodePoint::TwoGrayPlatm( IplImage* pSrcImage,IplImage* pDstImage)
{
	
	int blockSize=200;
	IplImage* pThrImage=cvCreateImage(cvSize(pSrcImage->width/blockSize,pSrcImage->height/blockSize),pSrcImage->depth,1);
	cvZero(pThrImage);
	int dx,dy;
	int nThrData=0;
	int i=0;
	int j=0;
	
	for (i=0;i<pThrImage->height;i++)
	{
		for (j=0;j<pThrImage->width;j++)
		{
		
			if ((j+2)*blockSize>pSrcImage->width)
			{
				dx=pSrcImage->width-j*blockSize;		
			}
			else
			{
				dx=2*blockSize;
			}
			if ((i+2)*blockSize>pSrcImage->height)
			{
				dy=pSrcImage->height-i*blockSize;
			}
			else
			{
				dy=2*blockSize;
			}
					
				int nThrData=otsu(pSrcImage,j*blockSize,i*blockSize,dx,dy);
				((uchar*)(pThrImage->imageData+i*pThrImage->widthStep))[j]=nThrData;
			
		}
	}
	cvResize(pThrImage,pDstImage,CV_INTER_LINEAR);
	
	cvReleaseImage(&pThrImage);
	
	
	
}



/*************************************************************
*函数名称:TwoGray()
*函数功能:二值化灰度图
*输入参数:原始灰度图指针
*输出参数二值化后的图象指针
*最后修改:2017年9月30日 张逸骅	 
*****************************************************************/
void DetectCodePoint::TwoGray(IplImage* gray,IplImage* imageplat,IplImage* twogray)
{
//	IplImage* twogray=cvCreateImage(cvSize(gray->width,gray->height), IPL_DEPTH_8U, 1);
	cvZero(twogray);
	int width=gray->width;
	int height=gray->height;
	int widthstep1=gray->widthStep;
	int widthstep2=imageplat->widthStep;
	int widthstep3=twogray->widthStep;	
	uchar* resout_data=(unsigned char*)(twogray->imageData);
	uchar* graydata= (unsigned char*)(gray->imageData);
	uchar*  platdata= (unsigned char*)(imageplat->imageData);
	for (int j=0;j<height;j++)
	{
		for (int i=0;i<width;i++)
		{
			int gray=((uchar*)(graydata+j*widthstep1))[i];
			int throsh=((uchar*)(platdata+j*widthstep2))[i];
			if (gray>throsh)
			{
				((uchar*)(resout_data+j*widthstep3))[i]=255;
			}
		}
	}
}



/***********************************************************
*函数名称: SmothImage();
*函数功能:平滑滤波
*输入参数:IplImage* grayimage ----进行平滑滤波的原始图象指针
*输出参数:IplImage* smothimage----滤波后的图形指针
*最后修改:2017年9月30日 张逸骅	 
*********************************************************/
IplImage* DetectCodePoint::SmothImage(IplImage* grayimage )
{
	IplImage* smothimage=cvCreateImage(cvSize(grayimage->width,grayimage->height), IPL_DEPTH_8U, 1);
	cvSmooth( grayimage , smothimage, CV_BLUR, 3, 3, 0, 0 );
	return  smothimage;
}



/**********************************************************
*函数名称:HistImage(IplImage* Gsmothimage,IplImage* histimage);
*功能:求输入图形的直方图均衡化图形
*输入参数:指向平滑后灰度图
*输出参数:直方图均衡化后的图象指针
*最后修改:2017年9月30日 张逸骅	 
************************************************************/
IplImage*  DetectCodePoint::HistImage(IplImage* smothimage)
{
	IplImage* histimage= cvCreateImage(cvSize(smothimage->width,smothimage->height), IPL_DEPTH_8U, 1);
	CvHistogram *hist = 0;
	int n = HDIM;     
    double nn[HDIM];
    uchar T[HDIM];
    CvMat *T_mat;
    
    int x;
    int sum = 0; // sum of pixels of the source image 图像中象素点的总和
    double val = 0;
	// calculate histgram 计算直方图
    hist = cvCreateHist( 1, &n, CV_HIST_ARRAY, 0, 1 );  
    cvCalcHist( &smothimage, hist, 0, 0 ); 
    
    // Create Accumulative Distribute Function of histgram
    val = 0;
    for ( x = 0; x < n; x++)
    {
        val = val + cvGetReal1D (hist->bins, x);
        nn[x] = val;
    }

    // Compute intensity transformation 计算变换函数的离散形式
    sum = smothimage->height * smothimage->width;
    for( x = 0; x < n; x++ )
    {
        T[x] = (uchar) (255 * nn[x] / sum); // range is [0,255]
    }

    // Do intensity transform for source image
    histimage = cvCloneImage( smothimage );
    T_mat = cvCreateMatHeader( 1, 256, CV_8UC1 );
    cvSetData( T_mat, T, 0 );    
    // directly use look-up-table function 直接调用内部函数完成 look-up-table 的过程
    cvLUT( smothimage, histimage, T_mat ); 
	return histimage;
	
}



/********************************************************************
*函数名称EdgeImage()
*功能:采用Canny算子对输入图象进行边缘检测
*输入参数:IplImage* Hist_Image
*输出参数:IplImage* edgeimage
*最后修改:2017年9月30日 张逸骅
********************************************************************/
IplImage* DetectCodePoint::EdgeImage(IplImage* Hist_Image,int edge_thresh)
{
	IplImage* edgeimage=cvCreateImage(cvSize(Hist_Image->width,Hist_Image->height), IPL_D
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值