yolo is written in C language, and the read image data is read according to the txt file, this time the main record is
list *plist = get_paths(train_images); //int N = plist->size; char **paths = (char **)list_to_array(plist);
It mainly introduces the origin and related introduction of these two functions. Some explanations are not clear and errors are welcome.
#include <stdio.h> #include <stdlib.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <stddef.h> typedef struct node{ void *val;//Pointer, the purpose is to point to the first pointer position of each line, used to store the string, *val refers to the first address of the string struct node *next;//This can be understood as a linked list, *next points to the next end of the linked list struct node *prev;//*prev points to the upper end of the linked list } node; typedef struct list{ int size; //This is the number of pictures, node *front;//It can be understood as the simplest binary tree, the depth is 2, there are only two children front and back, and there is a node structure in the front, we can see the node structure node *back; } list; void **list_to_array(list *l) { void **a = calloc(l->size, sizeof(void*)); int count = 0; node *n = l->front;/*Structure, the pointer address points to l->front, at this time n is the content in l->front*/ // node *n = l->back;/* I can't figure it out here, why is it front, not back. I think l->back is the data structure //Of course, my idea is wrong, I just don't understand the data structure*/ while(n){ a[count++] = n->val;//This while loop is to assign all strings in the linked list n to a[] n = n->next;//Continue to the next in the linked list n } return a; } list *make_list() { list *l = malloc(sizeof(list));//In the C language, the structure can no longer define the structure variable, but the structure pointer can be defined //In the C language, if the pointer does not open up space, it cannot be used directly // fprintf(stderr,"%d\n",sizeof(list));//The return is 24, which is to open up a space of 24 for the pointer l, about sizeof to find the size of the nested structure //I will give a brief introduction when I have time l->size = 0; l->front = 0; l->back = 0; return l; } char *fgetl(FILE *fp) { if(feof(fp)) return 0;//int type, check whether the file is over, if it is over, return 0 size_t size = 512; char *line = malloc(size*sizeof(char));//Create a space of 512. If the image path exceeds 512 characters, there will be problems. Of course, whose path will be so long? if(!fgets(line, size, fp)){/*Read a line from the file stream and send it to the buffer, the characters of each line cannot exceed size-1. When a newline character is encountered or the buffer is full, fgets will stop and return the data read */ free(line);//When free, the system will compare the address to see if it was applied for by malloc, if not, it will not be released //If so, the system knows how much memory to release, because the system has a record when malloc is performed. return 0; } } void list_insert(list *l, void *val) { node *new = malloc(sizeof(node));//Create space for new new, note that this new is always new new->val = val;//Assign the content of the parameter val to the val in new, in fact, this is to assign the image path string of each line to val new->next = 0;//The next one of new is 0, but the previous one still works if(!l->back){//If l-back is not empty l->front = new;//The front child of l is the new node string new->prev = 0; //l's previous child is 0 }else{//I don't really understand the purpose of the data structure here, so I can only talk about it. I hope that friends who understand it will have a wave of exchanges. l->back->next = new;//The next child of l's back is new new->prev = l->back;//The previous one of the new linked list is the back child of l, and new is the linked list /*Linked list, given the next value of this table, then also give the previous value, to be precise, this is to build the l->back linked list, the next one of l->back is new, and the upper part of this new One is l->back*/ } l->back = new;//l's back child is new ++l->size;//l-size records how many lines, that is, how many images } void file_error(char *s) { fprintf(stderr, "Couldn't open file: %s\n", s); exit(0); } list *get_paths(char *filename) { char *path; FILE *file = fopen(filename, "r");//Open file, file pointer name = fopen (file name, use file method) //"File pointer name" must be a pointer variable declared as FILE type; if(!file) file_error(filename); list *lines = make_list(); while((path=fgetl(file))){ //This involves a more complex data structure, and the text is difficult to describe list_insert(lines, path); } fclose(file); return lines; } intmain() { char *train_images = "/home/hjxu/Yolo/hjxu_train_code/2007_train.txt"; // char *copy = malloc(strlen(train_images)+1); // strncpy(copy, train_images, strlen(train_images)+1); // fprintf(stderr,"%s\n",copy); list *plist = get_paths(train_images); // fprintf(stderr, plist->size); char **paths = (char **)list_to_array(plist);//Convert the contents of plist into an array int i; for(i=0;i<plist->size;i++) { fprintf(stderr, "%s", *(paths+i));//**paths is this array, *(paths+i) is the i-th line, or paths[i] is fine } return 0; }
One thing I can't figure out, the data is always placed in the back of l, why is the front of l called, I hope my friends can help