将Yolo-v2检测到的目标单独保存成图像

最近想做一下这个东西,但是在网上找的博客上都说有bug,我心一横,决定自己改,过程很痛苦,但是很快乐!

如果代码有雷同,那真的是太巧了!

我最最开始看代码的时候发现detector.c中的line504(可能你的不太一样)

draw_detections(im, l.w*l.h*l.n, thresh, boxes, probs, names, alphabet, l.classes);
save_image(im, "predictions");
show_image(im, "predictions");

也就是说,Yolo将图像类重写了,写成了image类,这个可以在image.c中查看。仔细的人可能会发现,detector.c并非没有include  image类,而detector.c包含的demo.c包含了image类,里面将图像变成了一个结构体(在image.h中定义)

typedef struct {
    int h;
    int w;
    int c;
    float *data;
} image;

去image.c中查看draw_detections函数,发现它调用了

image im, int num, float thresh, box *boxes, float **probs, char **names, image **alphabet, int classes

在我的工程的287行定义了

int left  = (b.x-b.w/2.)*im.w;
int right = (b.x+b.w/2.)*im.w;
int top   = (b.y-b.h/2.)*im.h;
int bot   = (b.y+b.h/2.)*im.h;

也就是四个角的值,怎么理解呢像下图那样去理解~

将Yolo-v2检测到的目标单独保存成图像_第1张图片

然后我就定义了Rect的四个值

pre_x = left;
pre_y = top;
pre_h = bot - top;
pre_w = right - left;

这个声明我直接放在了最上面,然后写了一个save_cut_image的函数

void save_cut_image( int px, int py, int ph, int pw, int no)
{
	image copy = copy_image(m_img);
	if (m_img.c == 3) rgbgr_image(copy);
	int x, y, k;
	char buff[256];

	sprintf(buff, "results//%d.jpg", no);

	IplImage *disp = cvCreateImage(cvSize(m_img.w, m_img.h), IPL_DEPTH_8U, m_img.c);
	int step = disp->widthStep;
	for (y = 0; y < m_img.h; ++y) {
		for (x = 0; x < m_img.w; ++x) {
			for (k = 0; k < m_img.c; ++k) {
				disp->imageData[y*step + x*m_img.c + k] = (unsigned char)(get_pixel(copy, x, y, k) * 255);
			}
		}
	}
	CvMat *pMat = cvCreateMatHeader(m_img.w, m_img.h, IPL_DEPTH_8U);

	//char rect_name[256];

	//sprintf(rect_name, "%d_rect", no);

	CvRect rect = cvRect(px, py, pw, ph);

	cvGetSubRect(disp, pMat, rect);

	IplImage *pSubImg = cvCreateImage(cvSize(pw, ph), IPL_DEPTH_8U, m_img.c);

	cvGetImage(pMat, pSubImg);

	//printf("x=%d,y=%d,h=%d,w=%d\n", px, py, ph, pw);

	cvSaveImage(buff, pSubImg, 0);

	//cvReleaseImage(&disp);
	//cvReleaseImage(&pMat);
	//cvReleaseImage(&rect);

	//memset(&rect, 0, sizeof(rect));
	//cvReleaseImage(&pSubImg);
	//free(&rect);
	
	
	free_image(copy);
}

在draw_detections里进行了调用

save_cut_image( pre_x, pre_y, pre_h, pre_w, i);

主要的工作就是这些。这期间我遇到了一些bug,主要的一个就是

将Yolo-v2检测到的目标单独保存成图像_第2张图片

OpenCV Error: Assertion failed (udata < (uchar*)ptr && ((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*)+32)) in cv::fastFree, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\alloc.cpp, line 78

这个问题是在我的函数中,释放图像的那几步造成的,我已经注释掉了。

分割后的文件保存在results中,比如我输入

darknet_no_gpu.exe detector test data/coco.data cfg/yolo.cfg yolov2.weights -i 0 -thresh 0.25 dog.jpg

在results文件中就会生成以下图像: 

将Yolo-v2检测到的目标单独保存成图像_第3张图片

当我输入

darknet_no_gpu.exe detector test data/coco.data cfg/yolo.cfg yolov2.weights -i 0 -thresh 0.25 person.jpg

结果为

github链接

邮箱:[email protected]

 

你可能感兴趣的:(opencv,目标检测,yolo,YOLO目标检测)