C++ 如何開啟 RAW 圖檔 [OpenRAW 2.31]
解決的問題:
- 用什麼型態儲存更適合
- 控制開檔、讀檔、存檔與匯出檔案
- 繪製簡易的數值統計直方圖
- 使用 [] 下標存取 class 宣告的物件
- 方法 引入參數簡化
- 更有效率的取得遮罩
OpenRAW 2.31 refrence
如何引入使用
標頭僅需引入
使用時須使用命名空間
標頭僅需引入
#include "OpenRAW"
使用時須使用命名空間
namespace imr
可在標頭引入
using namespace imr;
typedef unsigned char imch;
typedef size_t imint;
namespace imr{
class ImrSize{
public:
ImrSize(imint y, imint x);
imint width;
imint high;
};
class ImrCoor{
public:
ImrCoor(int y, int x);
int y;
int x;
};
class ImrMask{
public:
ImrMask(ImrSize masksize);
private:
vector<imch> mask;
};
class imgraw {
public:
imgraw(ImrSize size);
private:
vector<imch> img_data;
};
};
各項類別屬性與建構說明
ImrSize 畫布大小
ImrSize
用來描述畫布畫布大小大小可在建構時設置
如,設置一個256x256大小的畫布
ImrSize size(256,256);
使用時可使用公開變數
型態為
size.width
與size.high
型態為
size_t
某些情況可需要轉態for (int i=0; i<=(int)size.high, ++i)
ImrCoor 座標位置
ImrCoor
用來描述座標位置座標可在建構時設置
如,設置一個(0,0)的座標
ImrCoor coor(0,0);
使用時可使用公開變數
型態為
size.y
與size.x
型態為
int
重載
ImrCoor
提供基本的加減乘除運算子 ImrCoor a(1,2), b(3,4), c;
c = a+b;
C則為(4,6)依此類推
ImrMask 遮罩陣列
ImrMask
用來儲存遮罩陣列使用時需再主程式宣告,並接住(複製)
方法產生的類別,即可使用。
ImrMask mask = img.getMask();
由於僅是接住方法產生的陣列
故不需建構任何資訊(由方法建構)
方法用法請參考該類別說明欄位
使用時可直接使用[下標]存取指標陣列
型態為
cout << mask[0] << endl;
mask[0] = 1;
型態為
unsigned char*
雖然為動態陣列,不過會智能解構
不必擔心主程式接住後記憶體釋放問題因為是動態陣列,主程式用複製的方式
只複製指標並不會拖垮效能
不過讀取的時候那仍然是複製數值
盡可能使用 maskVal() 取代
方法
imch & at2d(size_t y, size_t x);
以二維的方式存取位置(y,x)的遮罩
cout << mask.at2d(0,0);
mask.at2d(0,0) = 0;
void sort(size_t len, size_t start);
插入排序遮罩大小,由小到大
mask.sort();
排序全部
其中可以自由指定那些需要排序
比如說一共有4個我要排序中間兩個
長度是2,從mask[1]開始排序
sort(len, start);
比如說一共有4個我要排序中間兩個
長度是2,從mask[1]開始排序
mask.sort(2,1);
imgraw OpenRAW主要類別
imgraw
用來儲存RAW圖檔在建構時需設置圖檔大小
建構參數是
imgraw(ImrSize)
類別
如,設置一個256x256大小的圖檔
你也可以一起設置
ImrSize size(256,256);
imgraw img(size);
你也可以一起設置
imgraw img(ImrSize(256,256));
設置錯誤的圖檔大小,基於RAW檔特性
程式是無法辨別並自動修正的
可能會產生不可預知的錯誤
使用時可直接使用[下標]存取圖檔資訊
型態為
cout << img[0] << endl;
img[0] = 1;
型態為
vector<unsigned char>
注意因為型態是unsigned char
如果超出255將會從0開始計算
修正方式請在處理時轉為其他型態
img[0] = 127;
double temp;
temp = (double)img[0] + (double)255;
if (temp > 255){
temp=255;
}
img[0] = (unsigned char)temp;
方法
typedef unsigned char imch;
typedef size_t imint;
void read(string filename);
將檔案與主程式放到同一個位置
即可將圖檔讀入
img.read("File name");
即可將圖檔讀入
void write(string filename);
img.write("File name");
填入輸出的檔名,通常會在圖像處理完畢後輸出
imch & at2d(size_t y, size_t x);
以二維的方式存取圖檔資訊
cout << img.at2d(y, x) << endl;
img.at2d(y, x)=img.at2d(y, x)+10;
void resize_canvas(ImrSize size);
重新定義畫布大小
img.resize_canvas(ImrSize(high, width))
imint w();
獲得寬
img.w();
imint h();
獲得高
img.h();
void pri_htg(string title);
印出直方圖
img.pri_htg("title name");
void setMaskSize(ImrSize masksize);
設定遮罩大小,使用
getMask()
前須事先指定img.setMaskSize(ImrSize(3,3));
imch maskVal(ImrCoor ori, ImrCoor mas, ImrCoor shi);
取得遮罩數據
遮罩會自動檢查邊界,如果遇到邊界無法取值,自動補上邊界數值
遮罩會自動檢查邊界,如果遇到邊界無法取值,自動補上邊界數值
使用說明
對應原圖的點
ImrCoor ori();
對應原圖的點
ImrCoor mas();
遮罩二維位置
ImrCoor shi();
偏移位置(可省略預設 -1,-1)
假設
ori(1,1),
mas(2,2),
shi(-1,-1),
ori(1,1),
mas(2,2),
shi(-1,-1),
原圖(5x5)
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
遮罩參考點 ori(1,1)
○ ○ ○ ○ ○
○ ● ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
加上位移 shi(-1,-1)
● ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
放大這個部分
● ● ● ○ ○
● ● ● ○ ○
● ● ● ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
取 mas(2,2)
● ● ●
● ● ●
● ● ○
img.maskVal(ImrCoor(1,1), ImrCoor(2,2));
可得 [ 若shi留空,預設是shi(-1,-1) ]
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ● ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
ImrMask getMask(ImrCoor ori, ImrCoor shi);
取得遮罩陣列(一維)
需先設置遮罩大小img,setMaskSize(ImrSize(3,3));
點會複製到動態陣列上,除非有要排序,否則會比較花費時間
// 設定遮罩
img.setMaskSize(ImrSize(4,4));
// 取得Mask陣列及排續 getMask(原點位置)
ImrMask mask = img.getMask(ImrCoor(2,2));
cout << endl<< "setMaskSize" << endl;
for (int j = 0, c = 0; j < 4; ++j){
for (int i = 0; i < 4; ++i, c++){
cout << (int)mask[c] << " ";
// cout << mask.at2d(j,i);
}cout << endl;
}
原圖(5x5)
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
對應原圖的點
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ● ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
偏移位置 shi(-1,-1)
[ 若shi留空,預設是shi(-1,-1) ]
○ ○ ○ ○ ○
○ ● ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
獲得(4x4)
○ ○ ○ ○ ○
○ ● ● ● ●
○ ● ● ● ●
○ ● ● ● ●
○ ● ● ● ●