本篇提供了快速的記憶體切割技巧,利用memcpy以避免一個pixel一個pixel去拜訪的動作。
有做過embed system的朋友應該曉得,拜訪記憶體是一件很耗時間的事情,故在此分享。
※本篇程式碼只適用單通道的灰階影像(BYTE 0~255)
Image segmantation 切割記憶體coding邏輯原理如下:
Image segmantation 切割記憶體coding邏輯原理如下:
可想像使用小畫家時所使用的"矩形選取"然後擷取區塊。
矩形的右上角即為(startX,startY)矩形的寬高即為程式的seg_w、seg_h。
typedef unsigned char BYTE;
void SegMemery(int startX,int startY,BYTE* src,BYTE* dst,int src_w,int seg_h,int seg_w)
{
BYTE *Index_Seg,*Index;
int SegLenth,IndexLenth;
int start = startY, end = startY + seg_h;
/////////////////////////////////
SegLenth = seg_w*sizeof(BYTE);
IndexLenth = src_w*sizeof(BYTE);
/////////////////////////////////
Index_Seg = dst;
Index =src+ (start * src_w +startX)*sizeof(BYTE);
for(int i = start; i < end; i++)
{
memcpy(Index_Seg,Index , seg_w);
Index_Seg += SegLenth;
Index += IndexLenth;
}
}
以上即為影像切割之程式邏輯原理,
有影像切割就有影像貼上,memcpy邏輯相反而已。
若有疑問歡迎寫信,留言告知。
您好,
回覆刪除目前剛接觸影像處理的程式,
所以很高興您提供的程式讓我可以學習,
但程式碼也些不懂的地方想請教,
(1). dst代表是什麼呢?
(2) 為什麼以下這兩行還要乘上sizeof(BYTE)?
SegLenth = seg_w*sizeof(BYTE);
IndexLenth = src_w*sizeof(BYTE);
(3) 以及這行的Index不是很了解
Index =src+ (start * src_w +startX)*sizeof(BYTE);
希望大大可以解答:)
(1) 切割影像的結果指標頭。BTW因為此function沒有配置記憶體的功能,所以*src,*dst 本身都要是以配置記憶體空間的指標頭。
刪除(2)會使用sizeof(BYTE)是我一個處理記憶體位置的小習慣,我習慣去乘上一個型態的長度像是sizeof(BYTE)、sizeof(int)、sizeof(char)or sizeof(long)等,有點像是我知道要移位幾個int,但是int在記憶體的長度並非是1個BYTE而是4個BYTE。我認為這樣寫有一個好處就是,可適用於每個平台,因為未必每個平台 BYTE or int or long長度都一樣,畢竟BYTE這型態適用 "#typedef BYTE unsigned char"定義出來的,也許哪一天,有個討厭鬼故意在平台前面 #typedef BYTE unsigned short,那直接寫SegLenth = seg_w;與IndexLenth = src_w; debug起來就糗大了。
(3)我忘了說明此篇的影像都是已一維陣列表示,Index就是記憶體起始位置:
Index =src"影像空間指標頭"+ (start "startY影像位置y座標" * src_w "影像空間寬度"+startX"影像位置x標")*sizeof(BYTE);
故前面的 int start = startY, end = startY + seg_h;
指起始高度與終止高度
與後方的for(int i = start; i < end; i++)互相呼應