https://github.com/pjreddie/darknet
darknet/src/data.c
1、加載數據函數:對原始數據集做預處理,便於輸入網絡
matrix load_image_augment_paths(char **paths, int n, int min, int max, int size, float angle, float aspect, float hue, float saturation, float exposure, int center)
{
int i;
matrix X;
X.rows = n; //行
X.vals = calloc(X.rows, sizeof(float*)); //分配空間,大小爲 n*siezof(float*)
X.cols = 0; //列
for(i = 0; i < n; ++i){
//2、
image im = load_image_color(paths[i], 0, 0); //paths[i]:文件名
image crop;
if(center){
crop = center_crop_image(im, size, size); //center中心點座標?
} else {
crop = random_augment_image(im, angle, aspect, min, max, size, size);
}
//裁剪、色調、飽和度、曝光來調整圖像@nxt送入網絡之間對數據集做的預處理
int flip = rand()%2;
if (flip) flip_image(crop);
random_distort_image(crop, hue, saturation, exposure);
/*
show_image(im, "orig");
show_image(crop, "crop");
cvWaitKey(0);
*/
//grayscale_image_3c(crop);
free_image(im);
// crop是什麼圖像,爲什麼要將圖像轉存到到矩陣X中?
X.vals[i] = crop.data;
X.cols = crop.h*crop.w*crop.c;
}
return X;
}
2、加載圖像函數: load_image_color
現在的darknet找不到該函數,參考上面
image load_image_color(char *filename, int w, int h)
{
return load_image(filename, w, h, 3);
}
image load_image(char *filename, int w, int h, int c)
{
#ifdef OPENCV
image out = load_image_cv(filename, c); //文件名,通道數
#else
image out = load_image_stb(filename, c);
#endif
if((h && w) && (h != out.h || w != out.w)){
//按網絡要求調整到(w,h)大小,前提是輸入的w,h不要是0
image resized = resize_image(out, w, h);
free_image(out);
out = resized;
}
return out;
}
//讀圖像接口函數
image load_image_cv(char *filename, int channels)
{
IplImage* src = 0;
int flag = -1;
if (channels == 0) flag = -1;
else if (channels == 1) flag = 0; //grayscale image
else if (channels == 3) flag = 1; //3-channel color image
else {
fprintf(stderr, "OpenCV can't force load with %d channels\n", channels);
}
//opencv api load image
if( (src = cvLoadImage(filename, flag)) == 0 )
{
fprintf(stderr, "Cannot load image \"%s\"\n", filename);
char buff[256];
sprintf(buff, "echo %s >> bad.list", filename);
system(buff);
return make_image(10,10,3);
//exit(0);
}
//將讀取到的IplImage容器中的圖片裝入image結構中
image out = ipl_to_image(src);
cvReleaseImage(&src);
rgbgr_image(out); //convert BGR to RGB
return out;
}
darknet/src/image.c
//center_crop_image函數作用是什麼?
image center_crop_image(image im, int w, int h)
{
int m = (im.w < im.h) ? im.w : im.h; //得到w,h較小的值
image c = crop_image(im, (im.w - m) / 2, (im.h - m)/2, m, m);
image r = resize_image(c, w, h);
free_image(c);
return r;
}
image crop_image(image im, int dx, int dy, int w, int h)
{
image cropped = make_image(w, h, im.c);
int i, j, k;
for(k = 0; k < im.c; ++k){
for(j = 0; j < h; ++j){
for(i = 0; i < w; ++i){
int r = j + dy;
int c = i + dx;
float val = 0;
r = constrain_int(r, 0, im.h-1);
c = constrain_int(c, 0, im.w-1);
val = get_pixel(im, c, r, k);
set_pixel(cropped, i, j, k, val);
}
}
}
return cropped;
}
image make_image(int w, int h, int c)
{
image out = make_empty_image(w,h,c); //創建一個空白圖像
out.data = calloc(h*w*c, sizeof(float)); //給圖像動態分配空間
return out;
}
裁剪、色調、飽和度、曝光來調整圖像
void random_distort_image(image im, float hue, float saturation, float exposure)
{
float dhue = rand_uniform(-hue, hue);
float dsat = rand_scale(saturation);
float dexp = rand_scale(exposure);
distort_image(im, dhue, dsat, dexp);
}
void distort_image(image im, float hue, float sat, float val)
{
rgb_to_hsv(im); //將圖像從rgb轉換爲hsv
scale_image_channel(im, 1, sat);
scale_image_channel(im, 2, val);
int i;
for(i = 0; i < im.w*im.h; ++i){
im.data[i] = im.data[i] + hue;
if (im.data[i] > 1) im.data[i] -= 1;
if (im.data[i] < 0) im.data[i] += 1;
}
hsv_to_rgb(im);
constrain_image(im);
}
void scale_image_channel(image im, int c, float v)
{
int i, j;
for(j = 0; j < im.h; ++j){
for(i = 0; i < im.w; ++i){
float pix = get_pixel(im, i, j, c);
pix = pix*v; //改變點的像素值
set_pixel(im, i, j, c, pix);
}
}
}
static float get_pixel(image m, int x, int y, int c)
{
//assert:計算表達式 expression ,如果其值爲假(即爲0),那麼它先向stderr打印一條出錯信息,然後通過調用 abort 來終止程序運行。
assert(x < m.w && y < m.h && c < m.c);
return m.data[c*m.h*m.w + y*m.w + x];
}
static void set_pixel(image m, int x, int y, int c, float val)
{
if (x < 0 || y < 0 || c < 0 || x >= m.w || y >= m.h || c >= m.c) return;
assert(x < m.w && y < m.h && c < m.c);
m.data[c*m.h*m.w + y*m.w + x] = val;
}
void constrain_image(image im)
{
int i;
//im.data[i]表示什麼數據,爲什麼要將其二值化?
for(i = 0; i < im.w*im.h*im.c; ++i){
if(im.data[i] < 0) im.data[i] = 0;
if(im.data[i] > 1) im.data[i] = 1;
}
}
darknet/include/darknet.h
typedef struct {
int w; //weight
int h; //height
int c; //channel
float *data;
} image;
typedef struct matrix{
int rows, cols;
float **vals;
} matrix;
typedef struct{
int w, h;
matrix X;
matrix y;
int shallow;
int *num_boxes;
box **boxes;
} data;