/// <summary> /// 负样本检测专家,专门检测被误判为正的负样本和增加负样本集合 /// </summary> /// <param name="detectCollection">检测模块产生的区域集合</param> /// <param name="trackerRect">跟踪模块产生的区域</param> /// <param name="bmp">被检测的位图</param> /// <returns>返回最可信对象区域</returns> public Rectangle NegativeExpert(RectangleCollection detectCollection, RectangleF trackerRect, Bitmap bmp) { // 复制一个矩形集合是为了让NExpert独立与PExpert RectangleCollection newRectCollection = new RectangleCollection(); if (detectCollection != null) { foreach (Rectangle detectrect in detectCollection) { newRectCollection.Add(detectrect); } } if (trackerRect != Rectangle.Empty) { // 将跟踪到的目标也加入待评估的对象集合 newRectCollection.Add(new Rectangle((int)trackerRect.X, (int)trackerRect.Y, (int)trackerRect.Width, (int)trackerRect.Height)); } DateTime dt = DateTime.Now; // 最可信的对象 Rectangle confidentRect = MinDistanceObject(newRectCollection, bmp); double elapse = DateTime.Now.Subtract(dt).TotalMilliseconds; if (confidentRect != Rectangle.Empty) { newRectCollection.Remove(confidentRect); } dt = DateTime.Now; foreach (Rectangle rect in newRectCollection) { // 判断目标是否确实为背景,正距离归一化系数大于0.5 // 目标加入负样本队列的第一道关,目标必须看起来像负样本(正距离归一化系数大于0.5) if (MinDistance(rect, bmp) > Parameter.MEDIAN_COEF) { double areainsect = AreaProportion(confidentRect, rect); // 与最可信对象交集面积小于AREA_INTERSECT_PROPORTION的为负样本,加入负样本列表 if (areainsect < Parameter.AREA_INTERSECT_PROPORTION) { Bitmap patch = ImgOper.CutImage(bmp, rect.X, rect.Y, rect.Width, rect.Height); TrainNegative(patch); } } } elapse = DateTime.Now.Subtract(dt).TotalMilliseconds; return(confidentRect); }
/// <summary> /// 用模板去检测图像中的物体 /// </summary> /// <param name="bmpSource">源图像,需24位或32位真彩位图</param> /// <param name="template">基础分类器模板</param> /// <param name="fern">Fern</param> /// <returns></returns> public static RectangleCollection DetectObject(Bitmap bmpSource, BaseClassifierTemplate template, Fern fern) { RectangleCollection rc = new RectangleCollection(); Bitmap bmp = bmpSource; if (bmpSource.Width < template.BmpWidth || bmpSource.Height < template.BmpHeight) { return(null); } if (bmp != null && (bmp.PixelFormat == PixelFormat.Format24bppRgb || bmp.PixelFormat == PixelFormat.Format32bppRgb || bmp.PixelFormat == PixelFormat.Format32bppArgb)) { UInt32[] featurecode = null; bmp = ImgOper.Grayscale(bmpSource); int[,] igram = ImgOper.Integrogram(bmp, 1); while (template.BmpWidth < bmp.Width && template.BmpHeight < bmp.Height) { for (int y = 0; y < bmp.Height - template.BmpHeight + 1; y += (template.BmpHeight / 10)) { for (int x = 0; x < bmp.Width - template.BmpWidth + 1; x += (template.BmpWidth / 10)) { //int posnum = 0; //int negnum = 0; featurecode = BaseClassifierTemplate.GetFeatureCodeGroup(igram, bmp.Width, bmp.Height, template, x, y); double prob = 0; for (int i = 0; i < template.GroupNum; i++) { prob += fern.Probability[featurecode[i]]; //prob = fern.Probability[featurecode[i]]; //if (prob > 0.5) //{ // posnum++; //} //else //{ // negnum++; //} } prob = prob / template.GroupNum; if (prob > 0.5) //if (posnum > negnum) { Rectangle rect = new Rectangle(x, y, template.BmpWidth, template.BmpHeight); rc.Add(rect); } } } template.ResizeTemplate(1.2); } } return(rc); }
/// <summary> /// Hog检测, 被检测到图像自动缩放到BMPLIMITSIZE容忍范围内,并在检测完后将检测框自动放大之前缩小的倍率 /// </summary> /// <param name="bmp">位图</param> public RectangleCollection HogDetect(Bitmap bmp) { RectangleCollection resultCollection = null; if (bmp == null) { return(null); } if (NegCenter == null && PosCenter == null) { return(null); } DateTime dt = DateTime.Now; double elapse = 0; // 针对原图的缩放倍率 double se = 1; if (bmp.Width > Parameter.BMPLIMITSIZE.Width || bmp.Height > Parameter.BMPLIMITSIZE.Height) { se = bmp.Width / (double)Parameter.BMPLIMITSIZE.Width > bmp.Height / (double)Parameter.BMPLIMITSIZE.Height ? bmp.Width / (double)Parameter.BMPLIMITSIZE.Width : bmp.Height / (double)Parameter.BMPLIMITSIZE.Height; bmp = ImgOper.ResizeImage(bmp, (int)(bmp.Width / se), (int)(bmp.Height / se)); } bmp = ImgOper.Grayscale(bmp); //bmp = ImgOper.GaussianConvolution(bmp, GAUSSIAN_SIGMA, GAUSSIAN_SIZE); // 高斯卷积,使得图像平滑 // 所有层的检测结果 ArrayList resultlayers = new ArrayList(); // 初始缩放因子 double scalecoef = 1.0; Bitmap scalebmp = null; int newwidth = (int)(bmp.Width / scalecoef); int newheight = (int)(bmp.Height / scalecoef); // 每层最小距离点的集合 ArrayList idx_layermindistance = new ArrayList(); int cnt = 0; do { scalebmp = ImgOper.ResizeImage(bmp, newwidth, newheight); HogGram hogGram = HogGram.GetHogFromBitmap(scalebmp, Parameter.CELL_SIZE.Width, Parameter.CELL_SIZE.Height, Parameter.PART_NUMBER); NormBlockVectorGram blockGram = new NormBlockVectorGram(hogGram, Parameter.BLOCK_SIZE.Width, Parameter.BLOCK_SIZE.Height); DetectResultLayer detectlayer = new DetectResultLayer(); // !!!!!!检测窗口的像素尺寸必须能被cell尺寸整除!!!!!!像素尺寸除以hog尺寸就是检测窗口的尺寸 detectlayer.DetectResult = blockGram.DetectImgByHogWindow( new Size(Parameter.DETECT_WINDOW_SIZE.Width / Parameter.CELL_SIZE.Width, Parameter.DETECT_WINDOW_SIZE.Height / Parameter.CELL_SIZE.Height), NegCenter, PosCenter, Parameter.POS_DIST_COEF); if (detectlayer.DetectResult == null) { return(null); } detectlayer.ScaleCoef = scalecoef; resultlayers.Add(detectlayer); // 本层检测结果加入队列 scalecoef *= Parameter.SCALE_COEF; // 逐次缩小图像 newwidth = (int)(bmp.Width / scalecoef); newheight = (int)(bmp.Height / scalecoef); cnt++; } while (newwidth > 2 * Parameter.DETECT_WINDOW_SIZE.Width && newheight > 2 * Parameter.DETECT_WINDOW_SIZE.Height); elapse = DateTime.Now.Subtract(dt).TotalSeconds; // 框出所有可能的物体 WindowResult[] wr = null; Rectangle rect; double mindist = -1; WindowResult min_obj = null; double min_scalecoef = 1; resultCollection = new RectangleCollection(); foreach (DetectResultLayer layer in resultlayers) { wr = layer.DetectResult; for (int i = 0; i < wr.Length; i++) { if (wr[i].label == 1) { if (mindist == -1 || mindist > wr[i].PosDistance) { mindist = wr[i].PosDistance; min_obj = wr[i]; min_scalecoef = layer.ScaleCoef; } rect = new Rectangle((int)(wr[i].ImageRegion.X * layer.ScaleCoef * se), (int)(wr[i].ImageRegion.Y * layer.ScaleCoef * se), (int)(wr[i].ImageRegion.Width * layer.ScaleCoef * se), (int)(wr[i].ImageRegion.Height * layer.ScaleCoef * se)); resultCollection.Add(rect); } } } //rect = new Rectangle((int)(min_obj.ImageRegion.X * min_scalecoef * se), // (int)(min_obj.ImageRegion.Y * min_scalecoef * se), // (int)(min_obj.ImageRegion.Width * min_scalecoef * se), // (int)(min_obj.ImageRegion.Height * min_scalecoef * se)); //resultCollection.Add(rect); return(resultCollection); }