轉自:http://hi.baidu.com/fengjingge815/item/c44caaf0a7a2601ec6dc45f3 數字圖像處理--CImg類 class CImg?? { public: ?// 構造函數 ?CImg(); ?// Copy構造函數 ?CImg(CImg& gray); ?// 重載“=”操作符來創建新的對象 ?void operator = (CImg& gray); //圖像賦值
?BOOL operator == (CImg& gray); //判斷2幅圖像是否相同 ?CImg operator & (CImg& gray); //圖像按位與 ?CImg operator | (CImg& gray); //圖像按位或 ?CImg operator + (CImg gray); //圖像相加 ?CImg operator - (CImg& gray); //圖像減法 ?CImg operator ! (); //圖像反色 ?
?// 析構函數 ?virtual ~CImg();
public:? ? ?// 判斷位圖是否有效 ?BOOL IsValidate() { return m_pBMIH != NULL; }
?// 將所有像素的值初始化為color ?void InitPixels(BYTE color);
?// 從文件加載位圖 ?BOOL AttachFromFile(LPCTSTR lpcPathName); ?BOOL AttachFromFile(CFile &file); ?// 將位圖保存到文件 ?BOOL SaveToFile(LPCTSTR lpcPathName); ?BOOL SaveToFile(CFile &file);
?// 在DC上繪制位圖 ?BOOL Draw(CDC* pDC); ?BOOL Draw(CDC* pDC, CRect rt);
?// 設置像素的值 ?void SetPixel(int x, int y, COLORREF color); ?// 獲取像素的值 ?COLORREF GetPixel(int x, int y); ?// 獲取灰度值 ?BYTE GetGray(int x, int y);
?// 獲取一行的字節數 ?int GetWidthByte(); ?// 獲取一行的像素數 ?int GetWidthPixel(); ?// 獲取高度 ?int GetHeight();
?//改變位圖的尺寸 ?void ImResize(int nHeight, int nWidth); public:
?// 繪畫函數? ?// 繪制直線 ?void Line(POINT ptStart, POINT ptEnd); ?void Line(POINT ptStart, int nLen, int nWide, BOOL bHor); ?// 繪制矩形 ?void Rectangle(int x, int y, int r = 5); ?void Rectangle(POINT ptLT, int r = 5); ?void Rectangle(POINT ptLT, POINT ptRB); ?void Circle(int x, int y, int r = 5){};
public: ?// 判斷是否是二值圖像 ?BOOL IsBinaryImg(); ?// 判斷是否是索引圖像 ?BOOL IsIndexedImg(); ?// 256色索引圖像轉灰度圖像 ?bool Index2Gray();
?LPVOID GetColorTable(){return m_lpvColorTable;} ?int GetColorTableEntriesNum(){return m_nColorTableEntries;} private: ?void CleanUp();?
public: ?// 文件數據 ?BITMAPINFOHEADER *m_pBMIH; ?LPBYTE? *m_lpData; protected: ?int m_nColorTableEntries; ?LPVOID m_lpvColorTable; };
?
?
下文轉自:http://blog.163.com/xglla_1129/blog/static/81073510201061145439483/
CImg是一個跨平臺的C++的圖像處理庫,提供了加載、處理、顯示、保存等一系列功能,其中的圖像處理功能尤其強大。
CImg是一個跨平臺的C++的圖像處理庫,提供了加載、處理、顯示、保存等一系列功能,其中的圖像處理功能尤其強大。 首先,建議先到這里 欣賞一下使用CImg代碼做的Demo,就是它使我這個沒有圖像處理經驗的童鞋也心動得以致于研究了一星期^_^
主頁地址:http://cimg.sourceforge.net/ 下載地址:http://cimg.sourceforge.net/download.shtml 下載時注意應該下載源碼包,里面附帶的大量的例程。而實際上CImg庫只是一個頭文件CImg.h,這個頭文件里包含了CImg庫所有的代碼。 另外不要錯過下載列表中的一個部分完成的《CImg中文參考手冊 》。
CImg的Hello World 這段代碼是從《CImg參考手冊》里抄的,可以大致了解一下CImg的框架。 以VC為例:新建控制臺程序,輸入下面的代碼。項目屬性的鏈接器附加依賴項加入kernel.lib user32.lib gdi32.lib。最后,把CImg.h拷貝到項目路徑下,即可成功編譯運行
#include?"CImg.h" using?namespace?cimg_library; int?main()? { ????//?定義一個每個顏色?8?位(bit)的?640x400?的彩色圖像 ????CImg<unsigned?char>?img(640,400,1,3);?? ????//將像素值設為?0(黑色) ????img.fill(0);? ????//?定義一個紫色 ????unsigned?char?purple[]?=?{?255,0,255?}; ???? ????//?在坐標(100,?100)處畫一個紫色的“Hello?world” ????img.draw_text(100,100,"Hello?World",purple);?? ????//?在一個標題為“My?first?CImg?code”的窗口中顯示這幅圖像 ????img.display("My?first?CImg?code");?????????????????? ???? ????return?0; }? 運行這段代碼,顯示結果:
在CImg體系中,圖像有x,y,z,v四個軸,前三個當然是3維空間的三個方向(知道了吧?CImg可以處理3維圖像),第四個v一般表示色彩通道數,比如RGB三色就是3。
上面的代碼每行的注釋已經寫得很詳細,從代碼里可以看出CImg處于namespace cimg_library名空間之下;模板類CImg<> 是主要的圖像類,提供了大量的圖像處理方法。
在CImg庫里,還有一個重要的類是CImgDisplay ,它提供了一個顯示窗口,不僅可以顯示CImg的內容,還可以接收鍵盤鼠標事件,我們可以暫時把它看成是一個CImg專用窗體類。
CImg類介紹 CImg類提供的方法非常多,為了便于查閱,我用Doxygen重新生成了一份CImg庫的說明文檔,并做成chm格式,可以本文后面找到下載地址。 CImg模板類提供了圖像的載入、保存、處理功能,是整個庫的核心組件。它的聲明如下:
template<typename T> struct cimg_library::CImg;
模板參數T指明CImg中元素的類型。在自帶的參考手冊中稱這些元素為像素(pixel),不過因為這里的像素和我們平時的像素概念稍微有點不同。因為前面說過CImg體系中有xyzv四個軸,CImg手冊稱它為4維圖像,把4維圖像里的單個元素稱為像素。而事實上第四維的v通常就是我們的色彩通道,所以要在屏幕上顯示出一個真正的像素往往要取同一xyz軸上所有v軸的點(所有色彩通道合成一個真正的彩色像素)。在本文中我決定把這個組成圖像的最小單位稱為元素,由所有色彩通道v組成一個像素。
CImg類中的6個成員變量:
//?分別對應x,y,z,v四個軸的大小,即寬度、高度、深度和通道數。 unsigned?int?width,?height,?depth,?dim; //?指向內存中的圖像數據 T?*data; //?指明data是否是共用的,即是否有data的擁有權。 bool?is_shared; CImg類里的成員變量都是public的,我們可以直接存取它們,不過為了防止破壞完整性,建議使用成員方法如dimx(), dimy(), dimz(), dimv() 和ptr()來操作。
CImg的構造函數,大部分構造函數都很直白,就不列出了,可以查看手冊,下面列出的是一些特殊的構造函數。
//?以字符串指定的數據填充,其中的values字符串包含了一串十進制數字表示的數據。 //?比如參數values為字符串"20,30,40,50",?repeat_pattern為true時 //?圖像內的數據就以20,30,40,50,20,30,40,50,20...填充。 CImg?( ????const?unsigned?int?dx, ????const?unsigned?int?dy, ????const?unsigned?int?dz, ????const?unsigned?int?dv, ????const?char?*const?values, ????const?bool?repeat_pattern) //?由shared參數決定是否直接引用img中的data數據還是自己持有一份拷貝(是否共享) CImg?(const?CImg<?T?>?&img,?const?bool?shared) //?參考img的大小構造一個新的CImg對象 CImg?(const?CImg<?t?>?&img,?const?char?*const?dimensions) 這個構造函數的dimensions參數由一串數字或轉義符組成,分別對應x,y,z,v的大小。比如: 參數為"20 20 1 3"時新CImg對象的x,y,z,v的大小分別是20 20 1 3。 轉義符以%開頭,后綴可以是:
x, dx, dimx, width 表示img.width y, dy, dimy, height 表示img.height z, dz, dimz, depth 表示img.depth v, dv, dimv, dim 表示img.dim
比如CImg(img, "%y %x 1 3");可以生成一個和img的寬高正好互換的CImg對象。
//?從文件里載入圖像,文件類型由擴展名確定 CImg?(const?char?*const?filename) CImg庫本身支持BMP,RAW,HDR,INR,PGM,PPM,PAN,DLM格式 安裝了ImageMagick(Unix系)后可支持JPG,GIF,PNG,TIF等多種格式 CImg也能使用jpeg庫,zlib/png庫,tiff庫等來支持多種圖像格式,只需編譯時加入這些庫即可。可以到這里下載這些庫文件。
//?從CImgDisplay對象的內容創建圖像 CImg?(const?CImgDisplay?&disp) CImg部分成員方法 CImg提供了豐富的成員方法,在這里全部列出是不可能的,這里只作一些簡單介紹。更多方法請參考手冊。
//?賦值,它有多個重載的版本,參數和構造函數一樣,實際上構造函數最終都是調用它來實現的。 CImg<?T?>?&??assign?(); ? //?把data數據轉交給img,自己不再有data數據的擁有權 CImg<?T?>?&??transfer_to?(CImg<?T?>?&img); ? //?清除數據 CImg<?T?>?&??clear?(); ? //?獲得所有元素總數 unsigned?long??size?()?const ? //?獲得某個軸向的大小 int??dimx?()?const; int??dimy?()?const; int??dimz?()?const; int??dimv?()?const; ? //?取得遍歷元素的迭代器,這里的iterator其實就是T*。 iterator??begin?(); iterator??end?(); ? //?取得首尾數據 T?&??first?(); T?&??last?(); ? //?取得圖像內部數據(第二個版本取得數據并定位到指定位置) T?*??ptr?(); T?*??ptr?( ????const?unsigned?int?x, ????const?unsigned?int?y=0, ????const?unsigned?int?z=0, ????const?unsigned?int?v=0); ? //?快速存取指定位置上的數據 T?&??operator()?( ????const?unsigned?int?x, ????const?unsigned?int?y=0, ????const?unsigned?int?z=0, ????const?unsigned?int?v=0); ? //?按索引直接存取data數組 T?&??operator[]?(const?unsigned?long?off) ? //?得到指定位置的索引 long??offset?( ????const?int?x, ????const?int?y=0, ????const?int?z=0, ????const?int?v=0)?const; ? //?存取指定位置上的數據,當指定的軸的超出邊界時返回最邊上的值 T?&??at?(const?int?off); T&?atX(const?int?x,?const?int?y,?const?int?z,?const?int?v); T&?atXY(const?int?x,?const?int?y,?const?int?z,?const?int?v); T&?atXYZ(const?int?x,?const?int?y,?const?int?z,?const?int?v); T&?atXYZV(const?int?x,?const?int?y,?const?int?z,?const?int?v); ? //?存取指定位置上的數據,當指定的軸的超出邊界時返回out_val T?&??at?(const?int?off,?const?T?out_val); T&?atX(const?int?x,?const?int?y,?const?int?z,?const?int?v,?const?T?out_val); T&?atXY(const?int?x,?const?int?y,?const?int?z,?const?int?v,?const?T?out_val); T&?atXYZ(const?int?x,?const?int?y,?const?int?z,?const?int?v,?const?T?out_val); T&?atXYZV(const?int?x,?const?int?y,?const?int?z,?const?int?v,?const?T?out_val); 值得一提的是還有兩種插值版本的at方法,分別是線性插值和三次插值。其中線性插值以linear_作為前綴,三次插值以cubic_作為前綴。參數和上面的類似,只是各軸位置的類型不是int而是float,這批方法會按插值法算出小數點位置上的數據。
到這里可以發現CImg類實際上提供了類似于vector容器的編程接口,這樣我們的STL算法也能用于CImg的操作了,隨后就可以看到庫里有時也會把CImg類直接當作數據容器來使用。比如下面CImg中就有這個方法:
//?返回字符串的形式的圖像中的數據,默認是逗號分隔的一長串數字。 //這里返回的CImg<charT>不代表圖像,而是一個一維的字符串數據,這時它只是一個容器而已,可以把它看作是vector<charT>。 CImg<?charT?>??value_string?(const?char?separator=',',?const?unsigned?int?max_size=0); ?
上回 介紹了CImg模板類的一些函數,象我這種不在圖像處理行業混的人來說很多術語實在是太專業了-_-,不理不理,看不懂就直接寫測試代碼看它們的作用是什么不就知道啦~~嘿嘿^_^。
上測試代碼先:
#include?"CImg.h" using?namespace?cimg_library; ? int?main()? { ? ????CImg<unsigned?char>?src("test.bmp"); ????//?設置原圖大小,貌似haar計算要求圖像寬高是4的倍數 ????src.resize(?src.width-src.width%4,?src.height-src.height%4); ????CImgList<unsigned?char>?visu; ????visu ????????<<src.get_crop(0,0,src.width/2,src.height/2) ????????<<src.get_quantize(5) ????????<<src.get_rotate(45,1) ????????<<src.get_permute_axes("yxzv") ????????<<src.get_erode(5) ????????<<src.get_haar() ????????<<src.get_dilate(3) ????????<<src.get_blur(3) ????????<<src.get_noise(3) ????????<<src.get_deriche(3) ????????<<src.get_blur_anisotropic(8) ????????<<src.get_blur_bilateral(1,2) ????????<<src.get_blur_patch(4,3) ????????<<src.get_sharpen(3) ????????<<src.get_blur_median(3) ????????;?//如果愿意可以測試更多CImg的圖像處理方法 ??? ????//?用來顯示效果 ????CImgDisplay?disp(src.width*2,?src.height); ????int?i=0; ????unsigned?char?textcolor[]?=?{?255,255,255?}; ????while(!disp.is_closed?&&?!disp.is_keyQ?&&?!disp.is_keyESC) ????{ ????????i?=?i?%?visu.size; ????????char?buf[20]; ????????::sprintf(buf,"img:%d",i); ????????//顯示效果,(CImg?<<?CImg)會生成一個新的CImgList ????????//左邊是原圖,右邊是處理圖,外加寫了個序號在上面以便區別 ????????disp.display(?src?<<?(+visu[i]).draw_text(0,0,buf,textcolor)?).wait(); ????????//按方向鍵下則顯示下一個 ????????if(disp.is_keyARROWDOWN)?i++; ????????//方向鍵上則顯示上一個 ????????if(disp.is_keyARROWUP) ????????{ ????????????i--; ????????????if(i<0)?i=visu.size-1; ????????} ????} ????return?0; } 這個例子用到了CImg 、CImgList 、CImgDisplay 三個類。
CImg類 前面 已有介紹。
CImgList 是CImg的容器,用來保存一組CImg,主要方法有:
CImgList<T>&?remove(const?unsigned?int?pos)?//刪除指定位置 CImgList<T>&?pop_back()????????????//刪除最后一個 CImgList<T>&?pop_front()????????//刪除前端 CImgList<T>&?push_back(const?CImg<t>&?img)//從后面添加 CImgList<T>&?push_front(const?CImg<t>&?img)//從前面添加 CImgList<T>&?insert(const?CImg<t>&?img,?const?unsigned?int?pos)????//插入到指定位置之前 CImgList<T>&?clear()????//清空 CImg<T>&?operator[](const?unsigned?int?pos)?//取指定位置的圖像 上面這些是它作為容器的基本功能,同時它也重載了一些操作符以便于使用,比如本例中的"<<"操作其實就是push_back方法。另外,它還有大量的運算功能用于給容器中的圖像批量運算。最后,還有一些好玩的方法不可錯過:從視頻中載入或把圖像保存到視頻中:
CImgList<T>&?load_ffmpeg(const?char?*const?filename, ????const?unsigned?int?first_frame=0, ????const?unsigned?int?last_frame=~0U, ????const?unsigned?int?step_frame=1, ????const?bool?pixel_format=true, ????const?bool?resume=false) ? const?CImgList<T>&?save_ffmpeg( ????const?char?*const?filename, ????const?unsigned?int?first_frame=0, ????const?unsigned?int?last_frame=~0U, ????const?unsigned?int?fps=25) 這兩個方法要求鏈接ffmpeg庫,如果沒有這個庫文件,還可以使用load_ffmpeg_external和save_ffmpeg_external方法調用已外部安裝的ffmpeg 程序編解碼。
CImgDisplay類 是一個窗口類,它主要用來顯示CImg和CImgList。一般使用它的流程是:
新建CImgDisplay對象 設置它的大小,除直接輸入寬高外也能用直接用CImg、CImgList或另一個CImgDisplay對象作為調整大小的依據。這時,CImgDisplay對象內部已經建立了一個窗口了。 使用display方法顯示圖像 使用wait方法等待事件發生(鍵盤、鼠標、超時等) 檢查is_keyXXXX、is_closed、button、wheel等成員變量確定是什么事件,再決定我們該做什么操作。 如果需要,循環回第三步 析構時窗口收回。 在本例中,如果窗體關閉或按了Q鍵或按了ESC鍵則退出循環,程序結束。或者顯示由原圖和處理后的圖組成的CImgList圖像,如果按了上下方向鍵,則改變當前顯示的處理圖。
這是本例運行時的截圖: 水墨畫風格的《清明上河圖》
CImg的圖像處理方法絕不止上面例子中寫的那么一點點,
?
CImg庫不僅可以處理二維圖像,也能處理三維圖像,這篇文章介紹了CImg處理三維圖像的方法。
之前我們一直玩的是CImg的二維圖像處理,從CImg<>類的成員方法上看,顯然它還有更多能力。比如那些帶3d后綴的方法顯然是為三維圖像準備的,還有dijkstra方法,貌似是圖論方面的內容,CImg庫管得可真夠寬的-_- 圖論方面的先不管它,這方面還是Boost::Graph 比較在行,我比較感興趣的還是它的三維能力,畢竟這是個Head Only的跨平臺庫,并且沒有調用OpenGL,有三維處理能力還是蠻讓人興奮D~~,呵呵:)
現在,我們從一根三維的直線開始:
下面的代碼使用VC2005 Express編譯,為了直觀,使用了中文變量名.
#include?"CImg.h" using?namespace?cimg_library; ? //三維直線 int?main() { ????CImg<>?頂點(2,3,1,1, ????????0,50 ????????0,50 ????????0,50); ????CImgList<unsigned?int>?圖元(?CImg<unsigned?int>::vector(0,1)?); ????CImg<>?不透明度?=?CImg<>::vector(1.0f); ????CImgList<unsigned?char>?顏色表(?CImg<unsigned?char>::vector(255,0,255)?); ? ????//300*300,深度是1,3個色彩通道,以0填充 ????CImg<>?visu(300,300,1,3,0); ????visu.display_object3d("三維直線",頂點,圖元,顏色表,不透明度); ??? ????return?0; } 編譯運行,顯示一條直線,在窗體內按住鼠標拖曳,可以改變視角.不過就一根直線看上去不是很爽,沒立體感,下面我們用直接組成一個立方體:
一個立方體有8個頂點, 12條邊
//多根三維直線 int?main() { ????//?8個頂點 ????CImg<>?頂點(8,3,1,1, ????????0,??0,??50,?50,?50,?0,??0,??50, ????????0,??50,?50,?0,??0,??0,??50,?50, ????????0,??0,??0,??0,??50,?50,?50,?50); ????//?12條邊 ????CImgList<unsigned?int>?圖元?= ????????CImg<unsigned?int>::vector(0,1)?<< ????????CImg<unsigned?int>::vector(1,2)?<< ????????CImg<unsigned?int>::vector(2,3)?<< ????????CImg<unsigned?int>::vector(3,4)?<< ????????CImg<unsigned?int>::vector(4,5)?<< ????????CImg<unsigned?int>::vector(5,6)?<< ????????CImg<unsigned?int>::vector(6,7)?<< ????????CImg<unsigned?int>::vector(0,5)?<< ????????CImg<unsigned?int>::vector(1,6)?<< ????????CImg<unsigned?int>::vector(2,7)?<< ????????CImg<unsigned?int>::vector(0,3)?<< ????????CImg<unsigned?int>::vector(4,7) ????????; ? ????CImg<>?不透明度(1,12,1,1,?1.0f); ????CImgList<unsigned?char>?顏色表(?12,?CImg<unsigned?char>::vector(255,0,255)?); ? ????//300*300,深度是1,3個色彩通道,以0填充 ????CImg<>?visu(300,300,1,3,0); ????visu.display_object3d("三維直線",頂點,圖元,顏色表,不透明度); ??? ????return?0; } 顯示圖如下:
在CImg里,一幅三維圖被分解成:頂點(vertices)和圖元(primitives)兩個部分。
頂點 是一個CImg<>對象,它存放三維圖中所有的頂點數據。這個CImg<>對象此時只是一個數據容器,我們姑且把它看作圖像的話,那么它相當于一個“寬(width)=頂點數,高(height)=3,深(depth)=1,色彩通道(dim)=1”的圖像,在“這個圖像指定x位置上的3個y軸數據(因為高度總是為3)”指明了頂點所在的x,y,z方位。
比如上例中的頂點規格為8*3*1*1,表明頂點數為8,后面的數據從縱向正好是8組三維方位數據。這里這樣寫只是為了方便,如果要運行期動態加入頂點,可以使用append方法,上面的頂點初始化代碼可以改寫成:
CImg<>?頂點; 頂點.append(CImg<>::vector(0,0,0),'x') ????.append(CImg<>::vector(0,50,0),'x') ????.append(CImg<>::vector(50,50,0),'x') ????.append(CImg<>::vector(50,0,0),'x') ????.append(CImg<>::vector(50,0,50),'x') ????.append(CImg<>::vector(0,0,50),'x') ????.append(CImg<>::vector(0,50,50),'x') ????.append(CImg<>::vector(50,50,50),'x'); 這里的靜態方法vector返回一個由它的所有參數組成的CImg<>對象,最多可接受16個輸入參數。vector生成的CImg<>對象中數據是按列排的,也就是說生成的CImg<>對象寬度總是1,高度正好是參數個數,(0,y)點上的數據對應第y個參數。
append方法把當前圖像和輸入的圖像按指定軸的方向合成一個新的圖像,這是就是以'x'軸方向把這些1X3的“圖像”合并到一起。順便說一下,CImg的大部分方法都是返回自身的引用,所以可以連續用.操作。
圖元 是組成三維圖的最小圖形,一般的三維處理都以三角形作為圖元,所以顯卡測試里有三角形生成速度一項,扯遠了~~:-P
在CImg中圖元是一個CImgList<unsigned int>對象,這個對象中所包含的每個CImg<unsigned int>是一組頂點索引,同樣是1Xn的。n個頂點組合成一個面,這個面就是一個圖元,所有圖元組成一個三維物體。
另外,顯示時還需要給出每個圖元的不透明度和顏色表(或紋理),不透明度 是CImg<float>對象,存放了與圖元數目同樣個數的浮點數據(同樣是縱向存放的),1.0表示不透明,0.0表示全透明,0~1之間的數據指定透明度。
顏色表 是一個CImgList<>數據,其中至少要有圖元數目個CImg<>對象,每個CImg<>以RGB的順序縱向存放了對應圖元的顏色數據(或者紋理,這個后面再說)。
在本例中我們的所有圖元都是直線,我們也可以用四個點把圖元描述成一個面,這樣,一個三維立方體誕生了:
#include?"CImg.h" using?namespace?cimg_library; ? //三維立方體 int?main() { ????//8個頂點 ????CImg<>?頂點; ????頂點.append(CImg<>::vector(0,0,0),'x') ????????.append(CImg<>::vector(0,50,0),'x') ????????.append(CImg<>::vector(50,50,0),'x') ????????.append(CImg<>::vector(50,0,0),'x') ????????.append(CImg<>::vector(50,0,50),'x') ????????.append(CImg<>::vector(0,0,50),'x') ????????.append(CImg<>::vector(0,50,50),'x') ????????.append(CImg<>::vector(50,50,50),'x'); ? ? ????CImgList<unsigned?int>?圖元?= ????????CImg<unsigned?int>::vector(0,1,2,3)?<< ????????CImg<unsigned?int>::vector(4,5,6,7)?<< ????????CImg<unsigned?int>::vector(0,1,6,5)?<< ????????CImg<unsigned?int>::vector(2,7,4,3) ????????; ? ????CImg<>?不透明度(1,12,1,1,?1.0f); ????CImgList<unsigned?char>?顏色表(?12,?CImg<unsigned?char>::vector(255,0,255)?); ????顏色表[0]?=?CImg<unsigned?char>::vector(255,0,0); ????顏色表[1]?=?CImg<unsigned?char>::vector(0,255,0); ????顏色表[2]?=?CImg<unsigned?char>::vector(0,0,255); ????//300*300,深度是1,3個色彩通道,以0填充 ????CImg<>?visu(300,300,1,3,0); ????visu.display_object3d("三維立方體",頂點,圖元,顏色表,不透明度,true,4,4,true); ??? ????return?0; } 對了,前面都忘說display_object3d方法了:
該方法聲明如下:
const?CImg<T>&?cimg_library::CImg<?T?>::display_object3d??(?CImgDisplay?&disp?/*或?const?char?*const?title*/,? ??const?CImg<?tp?>?&??points,? ??const?CImgList<?tf?>?&??primitives,? ??const?CImgList<?tc?>?&??colors,? ??const?to?&??opacities,? ??const?bool??centering?=?true,? ??const?int??render_static?=?4,? ??const?int??render_motion?=?1,? ??const?bool??double_sided?=?false,? ??const?float??focale?=?500,? ??const?float??specular_light?=?0.2f,? ??const?float??specular_shine?=?0.1f,? ??const?bool??display_axes?=?true,? ??float?*const???pose_matrix?=?0?? ?)? 參數很多,前面的五個不用多說,說說后面幾個我知道的:-P
centering 指定是否把0,0,0點作為窗體中心 render_static和render_motion 指定靜態渲染級別和動態渲染級別: 0=點, 1=線, 2=面(沒有亮光), 3=面(平面), 4=面(邊緣柔和) double_sided 指定是否雙面渲染 focale 焦距
咳,由于空間想象力太差,組成立方體的六個面偶只放了四個,結果生成的圖形如下:
轉載于:https://www.cnblogs.com/milier-otw/archive/2013/03/13/2958101.html
總結
以上是生活随笔 為你收集整理的C++中图像处理的类之二 CImg 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。