CvMat CalculateBackProjection(CvMat _image, CvHistogram hist) { CvMat _backProject = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix); using (CvMat _imageHSV = ConvertToHSV(_image)) // Convert the image to HSV using (CvMat imgH = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix)) using (CvMat imgS = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix)) using (CvMat imgV = new CvMat(_image.Rows, _image.Cols, MonoColorMatrix)) { // Break image into H, S, V planes // If the image were BGR, then it would split into B, G, R planes respectively _imageHSV.CvtPixToPlane(imgH, imgS, imgV, null); // Cv.Split also does this // Store HSV planes as an IplImage array to pass to openCV's hist function // TODO: Why can't BackProjection accept CvMat? IplImage[] hsvPlanes = { Cv.GetImage (imgH), Cv.GetImage (imgS), Cv.GetImage (imgV)}; hist.CalcBackProject(hsvPlanes, _backProject); } return _backProject; }
/// <summary> /// バックプロジェクションにより肌色領域を求める /// </summary> /// <param name="imgSrc"></param> /// <param name="hsvPlanes"></param> /// <param name="imgRender"></param> private void RetrieveFleshRegion(IplImage imgSrc, IplImage[] hsvPlanes, IplImage imgDst) { int[] histSize = new int[] {30, 32}; float[] hRanges = {0.0f, 20f}; float[] sRanges = {50f, 255f}; float[][] ranges = {hRanges, sRanges}; imgDst.Zero(); using (CvHistogram hist = new CvHistogram(histSize, HistogramFormat.Array, ranges, true)) { hist.Calc(hsvPlanes, false, null); float minValue, maxValue; hist.GetMinMaxValue(out minValue, out maxValue); hist.Normalize(imgSrc.Width * imgSrc.Height * 255 / maxValue); hist.CalcBackProject(hsvPlanes, imgDst); } }