CvMat* HOGProcessor::calcHOGFromImage(char* filename, CvSize window, int normalization) { IplImage* im = cvLoadImage(filename); //Convert Image To 64x128 IplImage* dst = cvCreateImage(window,im->depth,im->nChannels); cvResize(im,dst); // Tinh integral histogram IplImage** integrals; integrals = calculateIntegralHOG(dst); CvMat* imgFeatureVector; imgFeatureVector = calcHOGWindow(integrals, cvRect(0, 0, window.width, window.height), normalization); for (int k = 0; k < NumOfBins; k++) cvReleaseImage(&integrals[k]); return imgFeatureVector; }
void detectHOG_impl(const cv::Mat &template_img, const cv::Mat &query_img, std::vector<cv::Rect> &detections, const double distanceThresh=50.0, const int offsetX=10, const int offsetY=10) { int maxWidth = query_img.cols-template_img.cols; int maxHeight = query_img.rows-template_img.rows; cv::Mat matching_cost_map(maxHeight, maxWidth, CV_32F, std::numeric_limits<float>::max()); cv::Mat template_img_gray, query_img_gray; cv::cvtColor(template_img, template_img_gray, cv::COLOR_BGR2GRAY); cv::cvtColor(query_img, query_img_gray, cv::COLOR_BGR2GRAY); // cv::equalizeHist(template_img_gray, template_img_gray); // cv::equalizeHist(query_img_gray, query_img_gray); #if 0 cv::HOGDescriptor hog_descriptor; cv::Mat template_descriptors = computeHOG(template_img_gray, hog_descriptor); for(int i = 0; i < matching_cost_map.rows; i += offsetY) { for(int j = 0; j < matching_cost_map.cols; j += offsetX) { cv::Mat sub_image = query_img_gray(cv::Rect(j, i, template_img.cols, template_img.rows)); cv::Mat query_descriptors = computeHOG(sub_image, hog_descriptor); double dist = cv::norm(template_descriptors, query_descriptors, cv::NORM_L2); matching_cost_map.at<float>(i,j) = (float) dist; } } #else std::vector<cv::Mat> template_integralImages = calculateIntegralHOG(template_img_gray, 9); std::vector<cv::Mat> query_integralImages = calculateIntegralHOG(query_img_gray, 9); cv::Mat template_hogCell; cv::Rect template_roi(0, 0, template_img_gray.cols, template_img_gray.rows); calculateHOG_rect(template_hogCell, template_integralImages, template_roi, 9, 3, 3); for(int i = 0; i < matching_cost_map.rows; i += offsetY) { for(int j = 0; j < matching_cost_map.cols; j += offsetX) { cv::Mat sub_image = query_img_gray(cv::Rect(j, i, template_img.cols, template_img.rows)); cv::Rect query_roi(j, i, template_img_gray.cols, template_img_gray.rows); cv::Mat query_hogCell; calculateHOG_rect(query_hogCell, query_integralImages, query_roi, 9, 3, 3); // double dist = cv::norm(template_hogCell, query_hogCell, cv::NORM_L2); double dist = cv::compareHist(template_hogCell, query_hogCell, cv::HISTCMP_BHATTACHARYYA); matching_cost_map.at<float>(i,j) = (float) dist; } } #endif #if DISPLAY_COST_MAP cv::Mat matching_cost_map_display; #endif double minVal, maxVal; cv::Point minLoc, maxLoc; cv::minMaxLoc(matching_cost_map, &minVal, &maxVal, &minLoc, &maxLoc); std::cout << "Min cost=" << minVal << " ; Max cost=" << maxVal << std::endl; #if DISPLAY_COST_MAP //Convert matching map for display matching_cost_map.convertTo(matching_cost_map_display, CV_8U, 255.0/(maxVal-minVal), -255.0*minVal/(maxVal-minVal)); #endif do { cv::minMaxLoc(matching_cost_map, &minVal, &maxVal, &minLoc, &maxLoc); // std::cout << "HOG distance=" << minVal << " ; distanceThresh=" << distanceThresh << std::endl; //"Reset the location" to find other detections #if 1 matching_cost_map.at<float>(minLoc.y, minLoc.x) = std::numeric_limits<float>::max(); #else //Not working int width = minLoc.x+template_img.cols < matching_cost_map.cols ? template_img.cols : matching_cost_map.cols-minLoc.x; int height = minLoc.y+template_img.rows < matching_cost_map.rows ? template_img.rows : matching_cost_map.rows-minLoc.y; cv::Rect detect_roi = cv::Rect(minLoc.x, minLoc.y, width, height); cv::Mat subregion = matching_cost_map(detect_roi); subregion = std::numeric_limits<float>::max(); #endif //Add detection detections.push_back(cv::Rect(minLoc.x, minLoc.y, template_img.cols, template_img.rows)); } while(minVal < distanceThresh); #if DISPLAY_COST_MAP cv::imshow("matching_cost_map_display", matching_cost_map_display); // cv::waitKey(0); #endif }
CvMat* HoGProcessor::train_64x128(char *prefix, char *suffix, CvSize window, int number_samples, int start_index, int end_index, char *savexml, int canny, int block, int normalization){ char filename[1000] = "\0", number[8]; int prefix_length; prefix_length = strlen(prefix); int bins = 9; /* A default block size of 2x2 cells is considered */ int block_width = m_block.width , block_height = m_block.height; /* Calculation of the length of a feature vector for an image (64x128 pixels)*/ int feature_vector_length; feature_vector_length = (((window.width - m_cell.width * block_width)/ (m_cell.width * m_fStepOverlap)) + 1) * (((window.height - m_cell.height * block_height) / (m_cell.height * m_fStepOverlap)) + 1) * (9 * m_block.height * m_block.width); /* Matrix to store the feature vectors for all(number_samples) the training samples */ CvMat* training = cvCreateMat(number_samples, feature_vector_length, CV_32FC1); CvMat row; CvMat* img_feature_vector; IplImage** integrals; int i = 0, j = 0; printf("Beginning to extract HoG features\n"); strcat(filename, prefix); /* Loop to calculate hog features for each image one by one */ for (i = start_index; i <= end_index; i++) { itoa(i,number,10); strcat(filename, number); strcat(filename, suffix); IplImage* im = cvLoadImage(filename); //Convert Image To 64x128 IplImage* dst = cvCreateImage(window,im->depth,im->nChannels); cvResize(im,dst); /* Calculation of the integral histogram for fast calculation of hog features*/ integrals = calculateIntegralHOG(dst); cvGetRow(training, &row, j); img_feature_vector = calculateHOG_window(integrals, cvRect(0, 0, window.width, window.height), normalization); cvCopy(img_feature_vector, &row); j++; printf("%s\n", filename); filename[prefix_length] = '\0'; for (int k = 0; k < 9; k++) { cvReleaseImage(&integrals[k]); } } if (savexml != NULL) { cvSave(savexml, training); } return training; }
CvRect HoGProcessor::detectObject(CvSVM *svmModel, IplImage *input, IplImage *result, CvRect rectHead, int normalization){ int StepWidth = 10; int StepHeight = 10; int nWindow = 3; int scaleWidth = 2; int scaleHeight = 2; ImageProcessor ip; //loai bo truong hop toc dai if(rectHead.height > rectHead.width) rectHead.height = rectHead.width; CvRect rectHuman = cvRect(rectHead.x + rectHead.width/2 - rectHead.width*scaleWidth/2, rectHead.y - 6, rectHead.width*scaleWidth, rectHead.height*scaleHeight); vector<CvRect> lstRect; CvMat* img_feature_vector; IplImage **newIntegrals; for(int i = 0; i < nWindow; i++) { for(int j = 0; j < nWindow; j++) { CvRect rect; rect.width = rectHuman.width + StepWidth*i; rect.height = rectHuman.height + StepHeight*j; rect.x = rectHuman.x - StepWidth*i/2; rect.y = rectHuman.y - StepHeight*j/2; if(rect.x < 0) rect.x = 0; if(rect.y < 0) rect.y = 0; if(rect.x + rect.width > input->width) rect.width = input->width - rect.x; if(rect.y + rect.height > input->height) rect.height = input->height - rect.y; IplImage* candidate_img = ip.getSubImageAndResize(input, rect, 48, 48); if(candidate_img) { newIntegrals = calculateIntegralHOG(candidate_img); img_feature_vector = calculateHOG_window(newIntegrals,cvRect(0,0,48,48),4); for (int k = 0; k < 9; k++) { cvReleaseImage(&newIntegrals[k]); } cvReleaseImage(newIntegrals); cvReleaseImage(&candidate_img); double predict_rs = svmModel->predict(img_feature_vector, true); if(predict_rs >= -1) lstRect.push_back(rect); cvReleaseMat(&img_feature_vector); } } } if(lstRect.size() > 0) { return MergeRect(lstRect); } return cvRect(0,0,-1,-1); }
CvMat* HoGProcessor::train_large(char *prefix, char *suffix, CvSize window, int number_images, int horizontal_scans, int vertical_scans, int start_index, int end_index, char *savexml, int normalization) { char filename[200] = "\0", number[8]; int prefix_length; prefix_length = strlen(prefix); int bins = 9; /* A default block size of 2x2 cells is considered */ int block_width = m_block.width , block_height = m_block.height; /* Calculation of the length of a feature vector for an image (64x128 pixels)*/ int feature_vector_length; feature_vector_length = (((window.width - m_cell.width * block_width) / (m_cell.width * m_fStepOverlap)) + 1) * (((window.height - m_cell.height * block_height) / (m_cell.height * m_fStepOverlap)) + 1) * (9 * m_block.height * m_block.width); /* Matrix to store the feature vectors for all(number_samples) the training samples */ CvMat* training = cvCreateMat(number_images * horizontal_scans * vertical_scans, feature_vector_length, CV_32FC1); CvMat row; CvMat* img_feature_vector; IplImage** integrals; int i = 0, j = 0; strcat(filename, prefix); printf("Beginning to extract HoG features from negative images\n"); /* Loop to calculate hog features for each image one by one */ for (i = start_index; i <= end_index; i++) { itoa(i,number,10); strcat(filename, number); strcat(filename, suffix); IplImage* im = cvLoadImage(filename); IplImage* img = im; //Chi xet nhung anh nao co kich thuoc lon hon hoac bang window if(im->width < window.width || im->height < window.height) { img = cvCreateImage(window,im->depth, im->nChannels); cvResize(im,img); } integrals = calculateIntegralHOG(img); for (int l = 0; l < vertical_scans - 1; l++) { for (int k = 0; k < horizontal_scans - 1; k++) { cvGetRow(training, &row, j); img_feature_vector = calculateHOG_window( integrals, cvRect(window.width * k, window.height * l, window.width, window.height), normalization); cvCopy(img_feature_vector, &row); j++; } cvGetRow(training, &row, j); img_feature_vector = calculateHOG_window( integrals, cvRect(img->width - window.width, window.height * l, window.width, window.height), normalization); cvCopy(img_feature_vector, &row); j++; } for (int k = 0; k < horizontal_scans - 1; k++) { cvGetRow(training, &row, j); img_feature_vector = calculateHOG_window( integrals, cvRect(window.width * k, img->height - window.height, window.width, window.height), normalization); cvCopy(img_feature_vector, &row); j++; } cvGetRow(training, &row, j); img_feature_vector = calculateHOG_window(integrals, cvRect(img->width - window.width, img->height - window.height, window.width, window.height), normalization); cvCopy(img_feature_vector, &row); j++; printf("%s\n", filename); filename[prefix_length] = '\0'; for (int k = 0; k < 9; k++) { cvReleaseImage(&integrals[k]); } cvReleaseImage(&img); } printf("%d negative samples created \n", training->rows); if (savexml != NULL) { cvSave(savexml, training); printf("Negative samples saved as %s\n", savexml); } return training; }