/// <summary> /// 取得一个样本的特征 /// </summary> /// <param name="bmpSource">源图像,需24位或32位真彩位图</param> /// <param name="template">基础分类器模板</param> /// <param name="sampletype">样本类型,1表示正样本,-1表示负样本</param> /// <returns>返回一个样本的特征</returns> public static SampleFeature GetSampleFeature(Bitmap bmpSource, BaseClassifierTemplate template, int sampletype) { SampleFeature sf = null; Bitmap bmp = bmpSource; if (bmp != null && (bmp.PixelFormat == PixelFormat.Format24bppRgb || bmp.PixelFormat == PixelFormat.Format32bppRgb || bmp.PixelFormat == PixelFormat.Format32bppArgb)) { // 将图像调整至模板大小 if (bmp.Width != template.BmpWidth || bmp.Height != template.BmpHeight) { bmp = ImgOper.ResizeImage(bmpSource, template.BmpWidth, template.BmpHeight); } bmp = ImgOper.Grayscale(bmpSource); int[,] igram = ImgOper.Integrogram(bmp, 1); sf = new SampleFeature(); sf.GroupNum = template.GroupNum; sf.FeatureNum = template.FeatureNum; sf.SampleType = sampletype; sf.FeatureValue = BaseClassifierTemplate.GetFeatureCodeGroup(igram, bmp.Width, bmp.Height, template, 0, 0); } return(sf); }
/// <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> /// 用训练好的模型测试已标记样本的类别 /// </summary> /// <param name="sample">已标记样本图像</param> /// <param name="template">基础分类器模板</param> /// <param name="fern">Fern</param> /// <returns>返回测试结果,类别</returns> public static int DetectSample(Bitmap sample, BaseClassifierTemplate template, Fern fern) { Bitmap bmp = null; if (sample.Width != template.BmpWidth || sample.Height != template.BmpHeight) { bmp = ImgOper.ResizeImage(sample, template.BmpWidth, template.BmpHeight); } else { bmp = sample; } if (bmp != null && (bmp.PixelFormat == PixelFormat.Format24bppRgb || bmp.PixelFormat == PixelFormat.Format32bppRgb || bmp.PixelFormat == PixelFormat.Format32bppArgb)) { bmp = ImgOper.Grayscale(bmp); int[,] igram = ImgOper.Integrogram(bmp, 1); UInt32[] featurecode = BaseClassifierTemplate.GetFeatureCodeGroup(igram, bmp.Width, bmp.Height, template, 0, 0); double prob = 0; for (int i = 0; i < template.GroupNum; i++) { prob += fern.Probability[featurecode[i]]; } prob = prob / template.GroupNum; if (prob > 0.5) { return(1); } else { return(-1); } } return(0); }
/// <summary> /// 获取一个检测窗口对应的图像中所有特征组 /// </summary> /// <param name="igram">积分图</param> /// <param name="gramwidth">图像宽度</param> /// <param name="gramheight">图像高度</param> /// <param name="template">模板</param> /// <param name="wx">检测窗口左上角X坐标</param> /// <param name="wy">检测窗口左上角Y坐标</param> /// <returns></returns> public static UInt32[] GetFeatureCodeGroup(int[,] igram, int gramwidth, int gramheight, BaseClassifierTemplate template, int wx, int wy) { UInt32[] featurevalue = new UInt32[template.GroupNum]; if (wx + template.BmpWidth > gramwidth || wy + template.BmpHeight > gramheight) { return(featurevalue); } for (int i = 0; i < template.GroupNum; i++) { UInt32 fvalue = 0; for (int j = 0; j < template.FeatureNum; j++) { fvalue = fvalue << 1; // 左移1位 Rectangle r = template.BitFeatures[i, j]; int x = r.X + wx; // 最左侧的x int y = r.Y + wy; // 最上面的y int w = r.Width; int h = r.Height; int xm = x + (w - 1) / 2; // 中间的x int ym = y + (h - 1) / 2; // 中间的y int xb = x + (w - 1); // 最右侧的x int yb = y + (h - 1); // 最下面的y if (r.Width > r.Height) // 横向特征 { int feature_left = igram[yb, xm] + igram[y, x] - igram[y, xm] - igram[yb, x]; int feature_right = igram[yb, xb] + igram[y, xm] - igram[y, xb] - igram[yb, xm]; if (feature_left > feature_right) { fvalue++; } } else if (r.Width == 1) // 纵向特征 { int feature_up = igram[ym, xb] + igram[y, x] - igram[y, xb] - igram[ym, x]; int feature_bottom = igram[yb, xb] + igram[ym, x] - igram[ym, xb] - igram[yb, x]; if (feature_up > feature_bottom) { fvalue++; } } } featurevalue[i] = fvalue; // 一个组中的特征数不能超过16个 } return(featurevalue); }