發表文章

色彩轉換結構應用C/C++的Struct與Union

這是一個關於我在影像處理程式中很想很久的問題, 可以用一個結構就能r,g,b存取一個像素,或是其他的色彩空間名稱,如xyz、yuv、ycbcr等。 不過寫出來之後還是不很理想,或許還是得用類別才是最好的解決方法。 利用的是結構中的巢狀匿名結構成員,這些匿名的結構中的成員最後都會成為最上層的結構的成員。 (from C++ Primer) #include <iostream > using namespace std; typedef struct {   union   {         struct         {               int r, g, b;         };                  // 當沒有變數名稱相同的時候          struct         {               float h, s, i;         };         // 當有變數名稱相同的時候          struct    ...

C/C++陣列初始化錯誤

有同學問我陣列給值的問題,這點在C++ Primer有寫到, 一些程式設計的書也會寫,只是一般同學都不會注意到"初始化"和"給值"是不同的。 #include <iostream > using namespace std; //正常作法-初始化 int inter_priority[6][6][4] =  { {{4,0,0,0},{4,3,2,1},{4,3,2,1},{4,2,3,1},{4,2,1,3},{4,0,0,0}}, {{4,3,2,1},{4,3,2,1},{4,3,2,1},{4,3,2,1},{4,2,1,3},{4,3,2,1}}, {{4,2,1,3},{4,3,2,1},{4,3,1,2},{4,3,2,1},{4,2,1,3},{4,3,1,2}}, {{4,1,3,2},{4,2,3,1},{4,3,1,2},{4,1,3,2},{4,1,2,3},{4,1,3,2}}, {{3,2,1,4},{4,2,1,3},{3,2,1,4},{4,2,1,3},{3,2,1,4},{3,2,1,4}}, {{4,0,0,0},{4,3,2,1},{4,3,1,2},{4,1,3,2},{4,2,1,3},{4,0,0,0}} }; // 同學的錯誤用法-當成給值 int inter_priority[6][6][4]; int main() { // 同學的錯誤用法-當成給值 inter_priority =  { {{4,0,0,0},{4,3,2,1},{4,3,2,1},{4,2,3,1},{4,2,1,3},{4,0,0,0}}, {{4,3,2,1},{4,3,2,1},{4,3,2,1},{4,3,2,1},{4,2,1,3},{4,3,2,1}}, {{4,2,1,3},{4,3,2,1},{4,3,1,2},{4,3,2,1},{4,2,1,3},{4,3,1,2}}, {{4,1,3,2},{4,2,3,1},{4,3,1,2},{4,1,3,2},{4,1,2,3},{4,1,3,2}}, {{3,2,1,4},{4,...

如何在命令提示字元中印出TAB字元

最簡單的方法,用SET指令輸入一個Tab SET TAB= echo This %TAB% is %TAB% a %TAB% demo %TAB% for %TAB% TAB %TAB% character.

一維陣列與二維陣列轉換

這是我今天不經意的寫出一個謬誤程式,我希望將一個用一維陣列儲存的100x100小圖片,放大2倍儲存到另一個二維陣列,放大方式就是將一個像素自我複製變成4個像素。   int FrameHeight = 480;   int FrameWidth = 640;   for(int h=0; h   {     for(int w=0; w     {       int idx1 = h*FrameWidth/4+w/2;       int idx2 = h/2*FrameWidth/2+w/2;       if (idx1 != idx2)       {         cerr << "(" << h <<  "," << w<< ") idx1=" << idx2 << " idx2=" << idx2 << endl;       }   } } idx1 = h*FrameWidth/4+w/2 idx2 = h/2*FrameWidth/2+w/2 idx1是對h*FrameWidth除以四 和 idx2先對h/2之後再除以2應該是一樣的吧!? 這個兩個運算看似數學上是相等且合理的,實際上卻是大大的不同! 實際上這兩個運算,因為使用了C/C++的整數運算特性,應表示成 idx1 = floor(h*FrameWidth / 4.0) + floor(w/2.0) idx2 = floor(floor(h / 2.0) * FrameWidth / 4.0) + floor(w/2.0) 當我們帶入 h, w為101, 100的時候 idx1 = 16210 = 16160 + 50 = floor(101 * 640 / 4.0) + ceil(100 / 2.0) idx2 ...

命令提示字元跑一連串的實驗

最近都在用command line幫忙跑實驗,不過總是會有些功能無法幫上忙。 因為是資工所,所以在遭遇不確定是否有提供某項的功能時,可善用熟悉的C/C++來解決它, 像是實驗用程式會在螢幕上輸出數據資料,因為每個實驗程式會輸出的數據不太一樣, 就可以寫一個簡單的parser去汲取所需資料,再用cout/cerr/printf輸出到螢幕上, 再用Command line的導向功能(>與>>或是2>,2>>)決定這些資料是否要輸出到檔案, 最近寫的一個Command line檔範例: SET BGRPATH=Images\ SET EXEPATH=GreenMSEOrderParser.exe for %%r in (3 4 5 6 7 8 9) do ( for %%v in ("%BGRPATH%*.bgr") do ( del /f GMSEOrder_%%~nv_R%%r.txt for %%t in (1 2 3 4 5 6 7 8 9) do ( set /p=%%~nv_T%%t   > GMSEOrder_%%~nv_R%%r.txt %EXEPATH% %%~nv_T%%t\*_R%%r*.mse >> GMSEOrder_%%~nv_R%%r.txt ) ) )

命令提字元的for迴圈從檔案列表處理資料

dir /B *.bmp > list.txt for /F  %%t in (list.txt) do (   DepthToYUV.exe %%t output.yuv ) pause

用命令提示字元將多個yuv圖檔合併成一個yuv序列

妥善利用Windows command line的copy指令, 就能將多個yuv圖檔合併成一個yuv序列。 copy NUL a.yuv copy /b a.yuv+*.yuv 我們知道YUV檔其實每一張Frame都只是連接著存放, 依照這個想法, 如果有很多張YUV圖片,都放在當前目錄下, 我們可能會用下面這種方式將yuv檔合併成一個a.yuv (低效率作法) dir /b *.yuv > ListFile.txt copy NUL a.yuv for /f %%x in (ListFile.txt) do ( rem echo %%x copy /b a.yuv+%%x ) del /F ListFile.txt 透過copy指令的特殊語法,我們也可以將yuv檔合併成一個a.yuv 簡便且高效率作法 copy NUL a.yuv  copy /b a.yuv+*.yuv 先用NUL 創立一個空檔案,然後把當前目錄下的所有檔案都拷貝過來 這個作法的缺點就是,檔案不見得會按照順序合併,因為*.yuv是由系統決定順序 我自己的測試是,就算檔名是連續的,還是不見得會照順序,可能是按檔案放到這個資料下的時間順序來處理的

用Maltab將jpg圖檔儲存成png無失真圖檔

用Maltab將jpg圖檔儲存成png無失真(lossless)圖檔,只需要一個只令呦! imwrite(img, filepath, 'Compression', 'none'); 下面給一個處裡一整個資料夾的範例,還會check是否與原圖一模一樣。 DoLosslessValidation = true; files=dir('*.jpg'); if size(files,1) <= 0     error('Cannot find any *.jpg files!'); end cnt = 0; valid_cnt = 0; for i=1:size(files,1)     [pathstr, name, ext] = fileparts(files(i).name);     img = imread(files(i).name);     if ~isempty(img)         imwrite(img, [name '_lossless.png'], 'Compression', 'none');               cnt = cnt+1;               if DoLosslessValidation             rec_img = imread([name '_lossless.png']);                       islossless = 0==sum(double(rec_img(:))-double(img(:)));                         ...

WinXP中的執行檔無法使用超過2.7G的記憶體

圖片
!這是在使用XP時找到的解法,可見我閒置多久未發表它了! 當EXE無法使用超過2.7G的記憶體, 可使用Visual Studio提供的系統工具 editbin 來解除WinXP的限制 在命令提示字元底(Command Line)底下輸入指令 editbin /LARGEADDRESSAWARE 指定要修改的EXE執行檔 關於editbin系統程式可以參考MSDN http://msdn.microsoft.com/zh-tw/library/xd3shwhf(v=vs.80).aspx 如果你無法執行editbin,但是你又有裝Visual Studio, 表示你需要使用VS的Command line捷徑來啟用VS系統工具。 例如: Microsoft Visual Studio 2008的Command line捷徑會在 「開始」→「程式集」→「Microsoft Visual Studio 2008」   →「Visual Studio Tools」→「Visual Studio 2008命令提示字元」

從命令提示字元執行Matlab的M檔程式

Command Line執行Matlab的M檔程式 1. 首先設定系統路徑,把Matlab的執行檔(含有matlab.exe的目錄)路徑 例如:Matlab 2011a的執行檔路徑為 C:\Program Files\MATLAB\R2011a\bin 2. 指令 matlab -nodesktop -nosplash -r M檔案的名稱(不需要含副檔名.m) 它就會run指定的.m檔囉! 這裡給一個Command line的應用,呼叫Matlab將Excel檔內的資料成圖片 for %%v in (test_videos\*.yuv) do ( matlab -nodesktop -nosplash -wait -r "xls2epsc('ExpRes_%%~nv.xlsx', 'RD_%%~nv.eps')" ) matlab的-wait選項是等待程式結束才繼續。