OpenCV學習心得(2) -- 建立一個類來簡化OpenCV的函數.

原创 2012年03月21日 19:05:23

轉載請注明出處與作者.

我們今後要做個工作是寫一個類,然後將OpenCV中的一些函數進行再次封裝以方便使用.(說實話OpenCV中好些函數的參數很難懂啊...)

需要說明的是我們這個類一般情況下是用來處理8-bit 圖像的.

下面是類的一些基本函數和變量

#include "opencv.hpp"
class COpenCVImage
{
public:
	COpenCVImage(void);
	~COpenCVImage(void);
public:
	typedef enum RGBQUAD_FILLTYPE //定義一個類型用來填充調色板,顯示單channel圖像的時候有效
	{
		RGBQUAD_FILLTYPE_GRAY=0,//用灰階圖像填充調色板
		RGBQUAD_FILLTYPE_RED, //用紅色填充調色板
		RGBQUAD_FILLTYPE_GREEN,//用綠色填充調色板
		RGBQUAD_FILLTYPE_BLUE, //用藍色填充調色板
		RGBQUAD_FILLTYPE_BLACKWHITE //用黑白色填充調色板
	};
protected:
	cv::Mat m_src; //源數據
	cv::Rect r_roi; //roi範圍
	cv::Mat m_draw; //用於顯示的數據
	bool m_modifyed_for_draw; //標記Src數據是否與顯示數據一致
	RGBQUAD_FILLTYPE m_rgbQuad_filltype; //當顯示單channel圖像的時候默認使用此調色板填充方式
};

再增加一些用於類型轉換的靜態函數

.h文件中

	//!對RECT進行正常化,即right>left, bottom>top.
	static RECT NormalizeRECT(const RECT& r); 
	//!對RECT進行縮放.此縮放為4個點的座標值同時縮放.
	static RECT RECT_ZOOM(const RECT& r,double zoomrate);
	//!將RECT轉換為cv::Rect類型
	static cv::Rect RECT2Rect(const RECT& sr) ;
	//!將cv::Rect轉換為RECT類型
	static RECT Rect2RECT(const cv::Rect& sr);
	//!填充BITMAPINFOHEADER,bmih空間需預先申請.width圖像的寬度,height圖像的高度,bpp圖像一個像素點要使用的bit數,一般為8,24,32等
	static void  Fill_BITMAPINFOHEADER( BITMAPINFOHEADER* bmih, int width, int height, int bpp);
	//!填充BITMAPINFO中的調色板信息,bmi中必須申請256種顏色空間.
	static void  Fill_RGBQUAD(BITMAPINFO *bmi,RGBQUAD_FILLTYPE type=RGBQUAD_FILLTYPE_GRAY);
	//!當internalRect有一部份或全部在externalRect的外部時,移動internalRect到externalRect的內邊界上(以左面和上面優先),如果internalRect完全在externalRect中則不進行移動.
	//!返回internalRect新位置的Rect.
	static cv::Rect Rect_MoveToInternalBorder(const cv::Rect& externalRect,const cv::Rect& internalRect);
public://獲取/設置 內部成員指針的函數,儘量不要使用這些指針.
	cv::Mat *GetSrcMat();
	cv::Mat *GetDrawMat();
	bool ModifyedForDraw();
	void SetSrcMat(const cv::Mat& m);
	void SetDrawMat(const cv::Mat& m);
	void ModifyedForDraw(bool modifyed);
	RGBQUAD_FILLTYPE RGBQUADFillType();
	void RGBQUADFillType(RGBQUAD_FILLTYPE type);


public://獲取源Mat的屬性
	bool Empty();
	int Width();
	int Height();
	int Channels();
	int Depth();
	cv::Rect GetRect();//此Rect是以(0,0)為頂點.


public://ROI設置
	//!設置ROI的Rect.如果未設置則為整個圖像的大小.
	void SetROIRect(const cv::Rect& r);
	//!得到ROI的Rect.如果未設置則為整個圖像的大小.
	cv::Rect GetROIRect();
	//!判斷ROI是否就是整個圖像.
	bool ROIisWhole();
	//!設置ROI為整個圖像
	void SetWholeAsROI();
.cpp文件中

RECT COpenCVImage::NormalizeRECT(const RECT& r )  
{  
   RECT rt=r; 
   if( r.left > r.right )  
   {  
      rt.left = r.right;  
      rt.right = r.left;  
   }  
   if( r.top > r.bottom )  
   {  
	   rt.bottom = r.top;  
      rt.top = r.bottom;  
   }  
   return rt;  
}  
RECT COpenCVImage::RECT_ZOOM(const RECT& r,double zoomrate)
{
	RECT rt=NormalizeRECT( r );
	RECT r2;
	r2.left=(LONG)(rt.left*zoomrate+0.5);
	r2.top=(LONG)(rt.top*zoomrate+0.5);
	r2.right=(LONG)(rt.right*zoomrate+0.5);
	r2.bottom=(LONG)(rt.bottom*zoomrate+0.5);
	return r2;
}
cv::Rect COpenCVImage::RECT2Rect(const RECT& sr )  
{  
   RECT srt = NormalizeRECT( sr );  
   return cv::Rect( srt.left, srt.top, srt.right - srt.left, srt.bottom - srt.top );  
}  
 
RECT COpenCVImage::Rect2RECT(const cv::Rect& sr )  
{  
   RECT dr;  
   dr.left = sr.x;  
   dr.top = sr.y;  
   dr.right = sr.x + sr.width;  
   dr.bottom = sr.y + sr.height;  
  
   return NormalizeRECT( dr );  
}
cv::Rect COpenCVImage::Rect_MoveToInternalBorder(const cv::Rect& externalRect,const cv::Rect& internalRect)
{
	cv::Point p;
	if(externalRect.x>internalRect.x)
	{
		p.x=externalRect.x;	
	}
	else if(externalRect.x+externalRect.width<internalRect.x+internalRect.width)
	{
		p.x=externalRect.x+externalRect.width-internalRect.width;
	}
	else
	{
		p.x=internalRect.x;
	}
	if(externalRect.y>internalRect.y)
	{
		p.y=externalRect.y;	
	}
	else if(externalRect.y+externalRect.height<internalRect.y+internalRect.height)
	{
		p.y=externalRect.y+externalRect.height-internalRect.height;
	}
	else
	{
		p.y=internalRect.y;
	}

	return cv::Rect(p.x,p.y,internalRect.width,internalRect.height);
}
void  COpenCVImage::Fill_BITMAPINFOHEADER( BITMAPINFOHEADER* bmih, int width, int height, int bpp)  
{  
   //assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));  
  if(bmih==NULL) return;
  
   memset( bmih, 0, sizeof(*bmih));  
   bmih->biSize = sizeof(BITMAPINFOHEADER);  
   bmih->biWidth = width;  
   bmih->biHeight = height;
   bmih->biPlanes = 1;  
   bmih->biBitCount = (unsigned short)bpp;  
   bmih->biCompression = BI_RGB;  
}  
void  COpenCVImage::Fill_RGBQUAD(BITMAPINFO *bmi,RGBQUAD_FILLTYPE type)
{
	RGBQUAD *rgb=(bmi->bmiColors);
	for(int i=0;i<256;++i)
	{
		switch(type)
		{
		  case RGBQUAD_FILLTYPE_GRAY://gray
			  rgb[i].rgbBlue=rgb[i].rgbGreen=rgb[i].rgbRed=(BYTE)i;
			  rgb[i].rgbReserved=0;
			  break;
		  case RGBQUAD_FILLTYPE_RED: //red
			  rgb[i].rgbBlue=rgb[i].rgbGreen=(BYTE)0;
			  rgb[i].rgbRed=(BYTE)i;
			  rgb[i].rgbReserved=0;
			  break;
		  case RGBQUAD_FILLTYPE_GREEN:
			  rgb[i].rgbBlue=rgb[i].rgbRed=(BYTE)0;
			  rgb[i].rgbGreen=(BYTE)i;
			  rgb[i].rgbReserved=0;
			  break;
		  case RGBQUAD_FILLTYPE_BLUE:
			  rgb[i].rgbGreen=rgb[i].rgbRed=(BYTE)0;
			  rgb[i].rgbBlue=(BYTE)i;
			  rgb[i].rgbReserved=0;
			  break;
		  case RGBQUAD_FILLTYPE_BLACKWHITE:
			  rgb[i].rgbBlue=rgb[i].rgbGreen=rgb[i].rgbRed=((i%2)?(BYTE)255:(BYTE)0);
			  rgb[i].rgbReserved=0;
		  default:
			  {
			  rgb[i].rgbBlue=rgb[i].rgbGreen=rgb[i].rgbRed=(BYTE)i;
			  rgb[i].rgbReserved=0;
			  }
		}
	}//for
}
cv::Mat *COpenCVImage::GetSrcMat()
{
	return &m_src;
}
cv::Mat *COpenCVImage::GetDrawMat()
{
	return &m_draw;
}
bool COpenCVImage::ModifyedForDraw()
{
	return m_modifyed_for_draw;
}
void COpenCVImage::ModifyedForDraw(bool modifyed)
{
	m_modifyed_for_draw=modifyed;
}
COpenCVImage::RGBQUAD_FILLTYPE COpenCVImage::RGBQUADFillType()
{
	return m_rgbQuad_filltype;
}
void COpenCVImage::RGBQUADFillType(COpenCVImage::RGBQUAD_FILLTYPE type)
{
	m_rgbQuad_filltype=type;
}
void COpenCVImage::SetSrcMat(const cv::Mat& m)
{
	m_src=m; 
}
void COpenCVImage::SetDrawMat(const cv::Mat& m)
{
	m_draw=m;
}
bool COpenCVImage::Empty()
{
	return m_src.empty();
}
int COpenCVImage::Width()
{
	return m_src.cols;
}
int COpenCVImage::Height()
{
	return m_src.rows;
}
int COpenCVImage::Channels()
{
	return m_src.channels();
}
int COpenCVImage::Depth()
{
	return m_src.depth();
}
cv::Rect COpenCVImage::GetRect()
{
	return cv::Rect(0,0,m_src.cols,m_src.rows);
}
void COpenCVImage::SetROIRect(const cv::Rect& r)
{
	r_roi=r;
}
cv::Rect COpenCVImage::GetROIRect()
{
	return r_roi;
}
bool COpenCVImage::ROIisWhole()
{
	if(r_roi==cv::Rect(0,0,m_src.cols,m_src.rows) )
	{
		return true;
	}
	return false;
}
void COpenCVImage::SetWholeAsROI()
{
	r_roi.x=r_roi.y=0;
	r_roi.width=m_src.cols;
	r_roi.height=m_src.rows;
}




opencv学习心得(一)鼠标响应事件绘制轮廓

//#include "gaosi.h" #include #include #include using namespace cv; using namespace std; //声明全局变...

opencv学习心得(六)新版本绘制外形轮廓。

最近在研究opencv2.3.1版本函数,因为函数结构使用C++类型的,所以在一些函数调用上有很多差别,但是在运行速度上提高不少,所以还是新版本好用。其实在新版本发布是,会有相关的使用手册,很多例子会...

OpenCV學習心得(5) -- 圖像通道分離

轉載請注明出處與作者 OpenCV提供了一個函數可以進行通道的分離,就是 cv::split. void split(const Mat& mtx, vector& mv); void sp...

opencv学习心得(六)新版本绘制外形轮廓

最近在研究opencv2.3.1版本函数,因为函数结构使用C++类型的,所以在一些函数调用上有很多差别,但是在运行速度上提高不少,所以还是新版本好用。其实在新版本发布是,会有相关的使用手册,很多例子会...

OpenCV學習心得(6) -- 圖像的縮放

轉載請著名出處與作者 OpenCV提供了一個實現圖像縮放的函數:cv::resize void resize(InputArray src, OutputArray dst, Size dsize...

OpenCV學習心得(7) -- 閾值處理

轉載請注明出處與作者 OpenCV提供了2個函數來處理閾值. 第一個函數 double threshold(InputArray src, OutputArray dst, double thr...

OpenCV學習心得(8) -- 直方圖的顯示

轉載請注明出處與作者 這裡只討論1維的直方圖 void calcHist(const Mat* arrays, int narrays, const int* channels, InputArr...

OpenCV學習心得(11) -- Mat類型與Arraya

轉載請注明出處與作者 下面對Mat矩陣進行一些說明: 1. cv::Mat中的數據不需要釋放.cv::Mat會自動釋放. 例如,cv::Mat m=cv::imread("123.jpg")...

opencv学习心得(四)——opencv提取截获图像

首先确定选区区域,这里利用鼠标选取区域具体操作看opencv学习心得(一)。 下面就是从感兴趣区域选取图像。 第一:创建图像空间,大小与rect相同。 第二:利用setroi选取区域。 第三:...

OpenCV學習心得(1) -- OpenCV的安裝

轉載請注明出處與作者. 最近需要用OpenCV寫一個工具.找來很多的文章來學習.但是發現不是英文的就是說的不清不楚的(至少對我的水平來說太高深了)..自己只好把自己的經驗寫下來以便以後查詢. 我是...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenCV學習心得(2) -- 建立一個類來簡化OpenCV的函數.
举报原因:
原因补充:

(最多只允许输入30个字)