///// <summary> ///// 将归一化后的向量列表写入文件,按照libsvm训练样本的格式 ///// </summary> ///// <param name="filepath">文件路径</param> ///// <param name="samplelabel">样本标签,1:正样本,-1:负样本</param> //public void WriteSamepleToFile(string filepath, int samplelabel) //{ // if (this.NormBlockVectors != null && this.NormBlockVectors.Count > 0) // { // FileStream fs = null; // StreamWriter sw = null; // try // { // fs = File.Open(filepath, FileMode.Append); // sw = new StreamWriter(fs); // sw.Write(samplelabel); // int cnt = 0; // foreach (object obj in this.NormBlockVectors) // { // double[] vec = (double[])obj; // for (int i = 0; i < vec.Length; i++) // { // cnt++; // if (vec[i] != 0) // { // sw.Write(" {0}:{1}", cnt, vec[i]); // } // } // } // sw.Write("\n"); // } // catch (Exception ex) // { // throw new Exception("File Operation fail!" + ex.Message); // } // finally // { // if (sw != null) // { // sw.Close(); // sw.Dispose(); // } // if (fs != null) // { // fs.Close(); // fs.Dispose(); // } // } // } //} ///// <summary> ///// 预测给出的特征向量所属分类 ///// </summary> ///// <param name="model">训练好的模型</param> ///// <param name="predictvec">待预测的特征向量</param> ///// <returns>返回预测值,1为正类,-1为负类</returns> //private double PredictVecClass(svm_model model, double[] predictvec) //{ // if (model != null && predictvec != null && predictvec.Length > 0) // { // svm_node[] x = new svm_node[predictvec.Length]; // for (int i = 0; i < predictvec.Length; i++) // { // x[i] = new svm_node(); // x[i].index = i + 1; // x[i].value_Renamed = predictvec[i]; // } // //DateTime dt = DateTime.Now; // double r = svm.svm_predict(model, x); // //double elapse = DateTime.Now.Subtract(dt).TotalMilliseconds; // return r; // } // else // { // return 0; // } //} #endregion /// <summary> /// 移动检测窗口匹配待检测图像,步长为一个Hog单元 /// </summary> /// <param name="hogwindowsize">检测窗口的hog尺寸</param> /// <param name="neg_center">负样本中心</param> /// <param name="pos_center">正样本中心</param> /// <param name="distancecoef">正距离系数,让检测到的目标物体稍微靠近正样本中心,排除决策边界上的点,一般取1.1到1.2之间</param> /// <returns>返回检测结果序列</returns> public WindowResult[] DetectImgByHogWindow(Size hogwindowsize, double[] neg_center, double[] pos_center, double distancecoef) { if (hogwindowsize.Width > HGram.HogSize.Width || hogwindowsize.Height > HGram.HogSize.Height || neg_center == null || pos_center == null) { return(null); } if (neg_center.Length != pos_center.Length) { return(null); } WindowResult[] windowresult = new WindowResult[(HGram.HogSize.Height - hogwindowsize.Height + 1) * (HGram.HogSize.Width - hogwindowsize.Width + 1)]; int cnt = 0; for (int row = 0; row < HGram.HogSize.Height - hogwindowsize.Height + 1; row++) { for (int col = 0; col < HGram.HogSize.Width - hogwindowsize.Width + 1; col++) { double neg_distance = 0; double pos_distance = 0; Rectangle rect = new Rectangle(col, row, hogwindowsize.Width, hogwindowsize.Height); double[] vec = GetHogWindowVec(rect); if (vec.Length != pos_center.Length) { return(null); } windowresult[cnt] = new WindowResult(); for (int i = 0; i < vec.Length; i++) { neg_distance += Math.Abs(vec[i] - neg_center[i]); pos_distance += Math.Abs(vec[i] - pos_center[i]); } windowresult[cnt].PosDistance = pos_distance; windowresult[cnt].NegDistance = neg_distance; if (pos_distance * distancecoef < neg_distance) { windowresult[cnt].label = 1; } else { windowresult[cnt].label = -1; } // 将HOG检测窗口转化为位图像素窗口 windowresult[cnt].ImageRegion = new Rectangle( HGram.StartX + col * HGram.CellSize.Width, HGram.StartY + row * HGram.CellSize.Height, hogwindowsize.Width * HGram.CellSize.Width, hogwindowsize.Height * HGram.CellSize.Height); cnt++; } } return(windowresult); }
/// <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); }