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

轉載請注明出處與作者.

我們今後要做個工作是寫一個類,然後將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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值