Several weeks ago, I got drown in adding data augmentation jitter to images, like rotation, mirror, scaling. When I read the source code line by line, a question abruptly bouncing back in my mind: how Caffe converts an image to blob? After some talks with my colleagues, I finally got the anwser:
The offcial Caffe says the conventional blob stores data in four dimension row-majored format: Batch*Channel*Height*Width
B*C*H*W. It means that in a 4D blob
N*C*H*W, the width changes fastest, then the height, channel, batch size N accordingly. Thus, given an image, we store it channel by channel (R, G, B channel respectively). For each channel plane, we scan it line by line (note the width changes fastest).
From the 4D blob aspect, we can intuitively implementation the code for an image as:
1 2 3 4 5 6 7 8
However, it is somewhat to index the
index_id for the image because
index_id jumps largely and irregularly around edges. Note that we, in most situations, start with an image and we might store the image line by line, with channel comes last. The official Caffe adopts this way. The relevant code is in
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
It is worthwhile noting that the index
(h, w, c) of the query image locates in
(c * height + h)*width + w 4D blob. Of course, we can implement the code in
(c, h, w) order and its index in the 4D blob is still
(c*height + h)*width + w.