/// <summary> /// 2次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx0">要素インデックスの,0を基準とした第1成分.</param> /// <param name="idx1">要素インデックスの,0を基準とした第2成分.</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">Histogram. </param> /// <param name="idx0">1st index of the bin.</param> /// <param name="idx1">2nd index of the bin.</param> /// <returns></returns> #endif public static double QueryHistValue_2D(CvHistogram hist, int idx0, int idx1) { var ret = NativeMethods.cvGetReal2D(hist.BinsPtr, idx0, idx1); GC.KeepAlive(hist); return(ret); }
/// <summary> /// n次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx">要素インデックスの配列(可変長引数)</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">1st index of the bin.</param> /// <param name="idx">Array of indices.</param> /// <returns></returns> #endif public static double QueryHistValue_nD(CvHistogram hist, params int[] idx) { var ret = NativeMethods.cvGetRealND(hist.BinsPtr, idx); GC.KeepAlive(hist); return(ret); }
/// <summary> /// ヒストグラムの正規化を行う. /// ビンの値の合計が factor に等しくなるようにスケーリングする事で,ヒストグラムのビンを正規化する. /// </summary> /// <param name="hist">ヒストグラムへの参照</param> /// <param name="factor">正規化係数</param> #else /// <summary> /// Normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to factor. /// </summary> /// <param name="hist">Reference to the histogram. </param> /// <param name="factor">Threshold level. </param> #endif public static void NormalizeHist(CvHistogram hist, double factor) { if (hist == null) { throw new ArgumentNullException("hist"); } NativeMethods.cvNormalizeHist(hist.CvPtr, factor); }
/// <summary> /// 2つの密なヒストグラムを比較する (cvCompareHist相当). /// 疎なヒストグラム,あるいは重み付けされた点が集まったような,より一般的な構造を比較するためには,関数cvCalcEMD2 を用いる方が良い場合もある. /// </summary> /// <param name="hist">比較対象の密なヒストグラム</param> /// <param name="method">比較手法</param> #else /// <summary> /// Compares two dense histograms. /// </summary> /// <param name="hist">target histogram</param> /// <param name="method">Comparison method.</param> /// <returns></returns> #endif public double Compare(CvHistogram hist, HistogramComparison method) { if (hist == null) { throw new ArgumentNullException("hist"); } return(NativeMethods.cvCompareHist(ptr, hist.CvPtr, method)); }
/// <summary> /// ヒストグラムの閾値処理を行う. /// 指定した閾値以下のヒストグラムのビンをクリアする. /// </summary> /// <param name="hist">ヒストグラムへの参照</param> /// <param name="threshold">閾値レベル</param> #else /// <summary> /// Clears histogram bins that are below the specified threshold. /// </summary> /// <param name="hist">Reference to the histogram. </param> /// <param name="threshold">Threshold level. </param> #endif public static void ThreshHist(CvHistogram hist, double threshold) { if (hist == null) { throw new ArgumentNullException("hist"); } NativeMethods.cvThreshHist(hist.CvPtr, threshold); }
//public Hist_Calculater(); public Hist_Calculater(String[] fs) { files = new List<String>(); hist_H = new List<CvHistogram>(); hist_S = new List<CvHistogram>(); hist_V = new List<CvHistogram>(); int sch = 0; int hist_size = 256; int[] hdims = { hist_size }; float[] hranges = { 0, 256 }; float[][] ranges = { hranges }; for (int i = 0; i < fs.Length; i++) { IplImage[] dst_img = new IplImage[4]; CvHistogram[] hist = new CvHistogram[4]; files.Add(fs[i]); IplImage temp = new IplImage(fs[i]); IplImage src_img = Cv.CreateImage(temp.Size, BitDepth.U8, 3); Cv.CvtColor(temp, src_img, ColorConversion.BgrToHsv); sch = src_img.NChannels; for (int j = 0; j < sch; j++) dst_img[j] = Cv.CreateImage(Cv.Size(src_img.Width, src_img.Height), src_img.Depth, 1); hist[0] = Cv.CreateHist(hdims, HistogramFormat.Array, ranges, true); //CvHistogram temph = Cv.CreateHist(hdims, HistogramFormat.Array, ranges, true); if(sch == 1) { Cv.Copy(src_img,dst_img[0]); } else { Cv.Split(src_img, dst_img[0], dst_img[1], dst_img[2], dst_img[3]); } for (int l = 0; l < sch; l++) { Cv.CalcHist(dst_img[l], hist[l], false); Cv.NormalizeHist(hist[l], 10000); if (l < 3) { Cv.CopyHist(hist[l], ref hist[l + 1]); } } hist_H.Add(hist[0]); hist_S.Add(hist[1]); hist_V.Add(hist[2]); } }
public Histogram() { // cvCalcHist // コントラストや明度をいろいろ変えられるサンプル const int histSize = 64; float[] range0 = { 0, 256 }; float[][] ranges = { range0 }; // 画像の読み込み using (IplImage srcImg = new IplImage(Const.ImageLenna, LoadMode.GrayScale)) using (IplImage dstImg = srcImg.Clone()) using (IplImage histImg = new IplImage(new CvSize(400, 400), BitDepth.U8, 1)) using (CvHistogram hist = new CvHistogram(new int[] { histSize }, HistogramFormat.Array, ranges, true)) { using (CvWindow windowImage = new CvWindow("image", WindowMode.AutoSize)) using (CvWindow windowHist = new CvWindow("histogram", WindowMode.AutoSize)) { // トラックバーが動かされた時の処理 CvTrackbar ctBrightness = null; CvTrackbar ctContrast = null; CvTrackbarCallback callback = delegate(int pos) { int brightness = ctBrightness.Pos - 100; int contrast = ctContrast.Pos - 100; // LUTの適用 byte[] lut = CalcLut(contrast, brightness); srcImg.LUT(dstImg, lut); // ヒストグラムの描画 CalcHist(dstImg, hist); DrawHist(histImg, hist, histSize); // ウィンドウに表示 windowImage.ShowImage(dstImg); windowHist.ShowImage(histImg); dstImg.Zero(); histImg.Zero(); }; // トラックバーの作成 // (OpenCVでは現在位置にポインタを渡すことでトラックバーの位置の変化が取得できるが、 // .NETではGCによりポインタが移動してしまうので廃止した。別の方法でうまく取得すべし。) ctBrightness = windowImage.CreateTrackbar("brightness", 100, 200, callback); ctContrast = windowImage.CreateTrackbar("contrast", 100, 200, callback); // 初回描画 callback(0); // キー入力待ち Cv.WaitKey(0); } } }
/// <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); } }
public Histogram() { // cvCalcHist const int histSize = 64; float[] range0 = { 0, 256 }; float[][] ranges = { range0 }; using (IplImage srcImg = new IplImage(FilePath.Image.Lenna, LoadMode.GrayScale)) using (IplImage dstImg = srcImg.Clone()) using (IplImage histImg = new IplImage(new CvSize(400, 400), BitDepth.U8, 1)) using (CvHistogram hist = new CvHistogram(new int[] { histSize }, HistogramFormat.Array, ranges, true)) { using (CvWindow windowImage = new CvWindow("image", WindowMode.AutoSize)) using (CvWindow windowHist = new CvWindow("histogram", WindowMode.AutoSize)) { CvTrackbar ctBrightness = null; CvTrackbar ctContrast = null; CvTrackbarCallback callback = delegate(int pos) { int brightness = ctBrightness.Pos - 100; int contrast = ctContrast.Pos - 100; // perform LUT byte[] lut = CalcLut(contrast, brightness); srcImg.LUT(dstImg, lut); // draws histogram CalcHist(dstImg, hist); DrawHist(histImg, hist, histSize); windowImage.ShowImage(dstImg); windowHist.ShowImage(histImg); dstImg.Zero(); histImg.Zero(); }; ctBrightness = windowImage.CreateTrackbar("brightness", 100, 200, callback); ctContrast = windowImage.CreateTrackbar("contrast", 100, 200, callback); // initial action callback(0); Cv.WaitKey(0); } } }
/// <summary> /// 2次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx0">要素インデックスの,0を基準とした第1成分.</param> /// <param name="idx1">要素インデックスの,0を基準とした第2成分.</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">Histogram. </param> /// <param name="idx0">1st index of the bin.</param> /// <param name="idx1">2nd index of the bin.</param> /// <returns></returns> #endif public static double QueryHistValue_2D(CvHistogram hist, int idx0, int idx1) { return CvInvoke.cvGetReal2D(hist.BinsPtr, idx0, idx1); }
/// <summary> /// ヒストグラムの計算 /// </summary> /// <param name="img"></param> /// <param name="hist"></param> private static void CalcHist(IplImage img, CvHistogram hist) { hist.Calc(img); float minValue, maxValue; hist.GetMinMaxValue(out minValue, out maxValue); Cv.Scale(hist.Bins, hist.Bins, ((double)img.Height) / maxValue, 0); }
/// <summary> /// ヒストグラムの描画 /// </summary> /// <param name="img"></param> /// <param name="hist"></param> /// <param name="histSize"></param> private static void DrawHist(IplImage img, CvHistogram hist, int histSize) { img.Set(CvColor.White); int binW = Cv.Round((double)img.Width / histSize); for (int i = 0; i < histSize; i++) { img.Rectangle( new CvPoint(i * binW, img.Height), new CvPoint((i + 1) * binW, img.Height - Cv.Round(hist.Bins[i])), CvColor.Black, -1, LineType.AntiAlias, 0 ); } }
/// <summary> /// 2次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx0">要素インデックスの,0を基準とした第1成分.</param> /// <param name="idx1">要素インデックスの,0を基準とした第2成分.</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">Histogram. </param> /// <param name="idx0">1st index of the bin.</param> /// <param name="idx1">2nd index of the bin.</param> /// <returns></returns> #endif public static double QueryHistValue_2D(CvHistogram hist, int idx0, int idx1) { return(NativeMethods.cvGetReal2D(hist.BinsPtr, idx0, idx1)); }
/// <summary> /// ヒストグラムのコピーを作成する (cvCopyHist相当). /// コピー先のヒストグラムへのポインタdstがnullの場合は,srcと同じサイズの新しいヒストグラムが作成される. /// それ以外の場合は,二つのヒストグラムは同一タイプ,サイズでないといけない. /// この関数はコピー元のヒストグラムのビンの値を,コピー先にコピーし, src内に定義されているのと同じビンの値域をセットする. /// </summary> /// <param name="dst">コピー先のヒストグラムへのポインタ. </param> #else /// <summary> /// Makes a copy of the histogram. /// If the second histogram dst is null, a new histogram of the same size as src is created. /// Otherwise, both histograms must have equal types and sizes. /// Then the function copies the source histogram bins values to destination histogram and sets the same bin values ranges as in src. /// </summary> /// <param name="dst">Reference to destination histogram. </param> #endif public void Copy(CvHistogram dst) { Cv.CopyHist(this, ref dst); }
// Takes an image and calculates its histogram for one channel. // Color images have 3 channels (4 if you count alpha?) // Webcam captures them in (R)ed, (G)reen, (B)lue. // Convert to (H)ue, (S)aturation (V)alue to get better separation for thresholding CvHistogram CalculateOneChannelHistogram(CvMat _image, int channelNum, float channelMax) { // Hue, Saturation, Value or HSV is a color model that describes colors (hue or tint) // in terms of their shade (saturation or amount of gray) // and their brightness (value or luminance). // For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255] if (channelNum > imColorChannels) Debug.LogError("Desired channel number " + channelNum + " is out of range."); float channelMin = 0; float[] channelRanges = new float[2] { channelMin, channelMax }; float[][] ranges = { channelRanges }; // Note: You don't need to use all 3 channels for the histogram. int channelBins = 32; // Number of bins in the Hue histogram (more bins = narrower bins) // Number of bins per histogram channel // If we use all 3 channels (H, S, V) then the histogram will have 3 dimensions. int[] hist_size = new int[] { channelBins }; CvHistogram hist = new CvHistogram(hist_size, HistogramFormat.Array, ranges, true); using (CvMat _imageHSV = ConvertToHSV(_image)) // Convert the image to HSV // We could keep the image in B, G, R, A if we wanted to. // Just split the channels into B, G, R planes using (CvMat imgChannel = new CvMat(_imageHSV.Rows, _imageHSV.Cols, MonoColorMatrix)) { // Break image into H, S, V planes // If the image were BGR, then it would split into B, G, R planes respectively switch (channelNum) { case 0: _imageHSV.CvtPixToPlane(imgChannel, null, null, null); // Cv.Split also does this break; case 1: _imageHSV.CvtPixToPlane(null, imgChannel, null, null); // Cv.Split also does this break; case 2: _imageHSV.CvtPixToPlane(null, null, imgChannel, null); // Cv.Split also does this break; default: Debug.LogError("Channel is out of range"); _imageHSV.CvtPixToPlane(imgChannel, null, null, null); // Cv.Split also does this break; } hist.Calc(Cv.GetImage(imgChannel), false, null); // Call hist function (no accumulatation, no mask) } return hist; // Return the histogram }
/// <summary> /// 2次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx0">要素インデックスの,0を基準とした第1成分.</param> /// <param name="idx1">要素インデックスの,0を基準とした第2成分.</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">Histogram. </param> /// <param name="idx0">1st index of the bin.</param> /// <param name="idx1">2nd index of the bin.</param> /// <returns></returns> #endif public static double QueryHistValue_2D(CvHistogram hist, int idx0, int idx1) { return NativeMethods.cvGetReal2D(hist.BinsPtr, idx0, idx1); }
/// <summary> /// OpnenCVでやってみる版 /// </summary> public void testCV(String ptn,Bitmap src) { int i, sch = 0; float[] range_0 = { 0, 256 }; float[][] ranges = { range_0 }; double tmp, dist = 0; IplImage src_img1, src_img2; IplImage[] dst_img1 = new IplImage[4]; IplImage[] dst_img2 = new IplImage[4]; CvHistogram[] hist1 = new CvHistogram[4]; CvHistogram hist2; //templateフォルダ以下にテンプレート画像を入れておく。 IEnumerable<string> tempFiles = Directory.EnumerateFiles(ptn, "*.bmp", SearchOption.TopDirectoryOnly); Dictionary<string, double> NCCPair = new Dictionary<string, double>(); //(1)二枚の画像を読み込む.チャンネル数が等しくない場合は,終了 //src_img1 = IplImage.FromFile(args[0], LoadMode.AnyDepth | LoadMode.AnyColor); src_img1 = (OpenCvSharp.IplImage)BitmapConverter.ToIplImage(src); // (2)入力画像のチャンネル数分の画像領域を確保 sch = src_img1.NChannels; for (i = 0; i < sch; i++) { dst_img1[i] = Cv.CreateImage(Cv.Size(src_img1.Width, src_img1.Height), src_img1.Depth, 1); } // (3)ヒストグラム構造体を確保 int[] nHisSize = new int[1]; nHisSize[0] = 256; hist1[0] = Cv.CreateHist(nHisSize, HistogramFormat.Array, ranges, true); // (4)入力画像がマルチチャンネルの場合,画像をチャンネル毎に分割 if (sch == 1) { Cv.Copy(src_img1, dst_img1[0]); } else { Cv.Split(src_img1, dst_img1[0], dst_img1[1], dst_img1[2], dst_img1[3]); } for (i = 0; i < sch; i++) { Cv.CalcHist(dst_img1[i], hist1[i], false); Cv.NormalizeHist(hist1[i], 10000); if (i < 3) { Cv.CopyHist(hist1[i], ref hist1[i + 1]); } } Cv.ReleaseImage(src_img1); foreach (string file in tempFiles) { try { dist = 0.0; src_img2 = IplImage.FromFile(file, LoadMode.AnyDepth | LoadMode.AnyColor); // (2)入力画像のチャンネル数分の画像領域を確保 //sch = src_img1.NChannels; for (i = 0; i < sch; i++) { dst_img2[i] = Cv.CreateImage(Cv.Size(src_img2.Width, src_img2.Height), src_img2.Depth, 1); } // (3)ヒストグラム構造体を確保 nHisSize[0] = 256; hist2 = Cv.CreateHist(nHisSize, HistogramFormat.Array, ranges, true); // (4)入力画像がマルチチャンネルの場合,画像をチャンネル毎に分割 if (sch == 1) { Cv.Copy(src_img2, dst_img2[0]); } else { Cv.Split(src_img2, dst_img2[0], dst_img2[1], dst_img2[2], dst_img2[3]); } // (5)ヒストグラムを計算,正規化して,距離を求める for (i = 0; i < sch; i++) { Cv.CalcHist(dst_img2[i], hist2, false); Cv.NormalizeHist(hist2, 10000); tmp = Cv.CompareHist(hist1[i], hist2, HistogramComparison.Bhattacharyya); dist += tmp * tmp; } dist = Math.Sqrt(dist); // (6)求めた距離を文字として画像に描画 Debug.WriteLine("{0} => Distance={1:F3}", file, dist); Cv.ReleaseHist(hist2); Cv.ReleaseImage(src_img2); } catch (OpenCVException ex) { Debug.WriteLine("Error : " + ex.Message); } } Cv.ReleaseHist(hist1[0]); Cv.ReleaseHist(hist1[1]); Cv.ReleaseHist(hist1[2]); Cv.ReleaseHist(hist1[3]); }
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> /// 輪郭の pair-wise geometrical histogram を求める /// </summary> /// <param name="hist">求められたヒストグラム.必ず2次元になる.</param> #else /// <summary> /// Calculates pair-wise geometrical histogram for contour /// </summary> /// <param name="hist">Calculated histogram; must be two-dimensional. </param> #endif public void CalcPGH(CvHistogram hist) { Cv.CalcPGH(this, hist); }
/// <summary> /// 一つのヒストグラムをもう一方のヒストグラムで割る (cvCalcProbDensity相当). /// </summary> /// <param name="hist1">一番目のヒストグラム(除数)</param> /// <param name="hist2">二番目のヒストグラム</param> /// <param name="dstHist">出力ヒストグラム</param> /// <param name="scale">出力ヒストグラムのスケール係数</param> #else /// <summary> /// Divides one histogram by another. /// </summary> /// <param name="hist1">first histogram (the divisor). </param> /// <param name="hist2">second histogram. </param> /// <param name="dstHist">destination histogram. </param> /// <param name="scale">scale factor for the destination histogram. </param> #endif public static void CalcProbDensity(CvHistogram hist1, CvHistogram hist2, CvHistogram dstHist, double scale) { Cv.CalcProbDensity(hist1, hist2, dstHist, scale); }
/// <summary> /// 一つのヒストグラムをもう一方のヒストグラムで割る (cvCalcProbDensity相当). /// </summary> /// <param name="hist1">一番目のヒストグラム(除数)</param> /// <param name="hist2">二番目のヒストグラム</param> /// <param name="dstHist">出力ヒストグラム</param> #else /// <summary> /// Divides one histogram by another. /// </summary> /// <param name="hist1">first histogram (the divisor). </param> /// <param name="hist2">second histogram. </param> /// <param name="dstHist">destination histogram. </param> #endif public static void CalcProbDensity(CvHistogram hist1, CvHistogram hist2, CvHistogram dstHist) { Cv.CalcProbDensity(hist1, hist2, dstHist); }
public void compare_Hist(Bitmap image, List<double> out_approx) { IplImage[] dst_img = new IplImage[4]; CvHistogram[] hist = new CvHistogram[4]; CvHistogram hist2; double tmp, dist = 0; List<double> appH = new List<double>(); List<double> appS = new List<double>(); List<double> appV = new List<double>(); List<double> outapp = new List<double>(); int hist_size = 256; int[] hdims = { hist_size }; float[] hranges = { 0, 256 }; float[][] ranges = { hranges }; IplImage src2 = (OpenCvSharp.IplImage)OpenCvSharp.Extensions.BitmapConverter.ToIplImage(image); IplImage src = Cv.CreateImage(src2.Size, BitDepth.U8, 3); Cv.CvtColor(src2, src, ColorConversion.BgrToHsv); int sch = src.NChannels; for (int j = 0; j < sch; j++) dst_img[j] = Cv.CreateImage(Cv.Size(src.Width, src.Height), src.Depth, 1); hist2 = Cv.CreateHist(hdims, HistogramFormat.Array, ranges, true); if (sch == 1) { Cv.Copy(src, dst_img[0]); } else { Cv.Split(src, dst_img[0], dst_img[1], dst_img[2], dst_img[3]); } hist[0] = Cv.CreateHist(hdims, HistogramFormat.Array, ranges, true); for (int l = 0; l < sch; l++) { Cv.CalcHist(dst_img[l], hist[l], false); Cv.NormalizeHist(hist[l], 10000); if (l < 3) { Cv.CopyHist(hist[l], ref hist[l + 1]); } } foreach (CvHistogram n in hist_H) { tmp = Cv.CompareHist(n, hist[0], HistogramComparison.Bhattacharyya); dist = tmp * tmp; appH.Add(Math.Sqrt(dist)); } foreach (CvHistogram n in hist_S) { tmp = Cv.CompareHist(n, hist[1], HistogramComparison.Bhattacharyya); dist = tmp * tmp; appS.Add(Math.Sqrt(dist)); } foreach (CvHistogram n in hist_V) { tmp = Cv.CompareHist(n, hist[2], HistogramComparison.Bhattacharyya); dist = tmp * tmp; appV.Add(Math.Sqrt(dist)); } Cv.ReleaseHist(hist2); Cv.ReleaseImage(src); int p = 0; foreach(double n in appH) { out_approx.Add((n + appS[p]) / 2); p++; } }
/// <summary> /// n次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx">要素インデックスの配列(可変長引数)</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">1st index of the bin.</param> /// <param name="idx">Array of indices.</param> /// <returns></returns> #endif public static double QueryHistValue_nD(CvHistogram hist, params int[] idx) { return CvInvoke.cvGetRealND(hist.BinsPtr, idx); }
/// <summary> /// n次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx">要素インデックスの配列(可変長引数)</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">1st index of the bin.</param> /// <param name="idx">Array of indices.</param> /// <returns></returns> #endif public static double QueryHistValue_nD(CvHistogram hist, params int[] idx) { return NativeMethods.cvGetRealND(hist.BinsPtr, idx); }
/// <summary> /// 2つの密なヒストグラムを比較する (cvCompareHist相当). /// 疎なヒストグラム,あるいは重み付けされた点が集まったような,より一般的な構造を比較するためには,関数cvCalcEMD2 を用いる方が良い場合もある. /// </summary> /// <param name="hist">比較対象の密なヒストグラム</param> /// <param name="method">比較手法</param> #else /// <summary> /// Compares two dense histograms. /// </summary> /// <param name="hist">target histogram</param> /// <param name="method">Comparison method.</param> /// <returns></returns> #endif public double Compare(CvHistogram hist, HistogramComparison method) { if (hist == null) { throw new ArgumentNullException("hist"); } return CvInvoke.cvCompareHist(_ptr, hist.CvPtr, method); }
/// <summary> /// n次元ヒストグラムの指定されたビンの値を返す. /// 疎なヒストグラムの場合で,既にビンが存在している場合以外は,この関数が新しいビンを作成し,0にセットする. /// </summary> /// <param name="hist">ヒストグラム</param> /// <param name="idx">要素インデックスの配列(可変長引数)</param> /// <returns>指定した要素の値</returns> #else /// <summary> /// Queries value of histogram bin. /// </summary> /// <param name="hist">1st index of the bin.</param> /// <param name="idx">Array of indices.</param> /// <returns></returns> #endif public static double QueryHistValue_nD(CvHistogram hist, params int[] idx) { return(NativeMethods.cvGetRealND(hist.BinsPtr, idx)); }
// Update and OnGUI are the main loops void Update() { if (DrawThresholdImageFlag) DrawThresholdImage(videoSourceImage); if (DoFaceTrack) DrawFaceTracking(videoSourceImage); FindObjectScreenPosition(); if (_webcamTexture.isPlaying) { if (_webcamTexture.didUpdateThisFrame) { //convert Unity 2D texture from webcam to CvMat Texture2DToCvMat(); // Do some image processing with OpenCVSharp on this image frame ProcessImage(videoSourceImage); } } else { Debug.Log("Can't find camera!"); } if (Input.GetKeyDown(KeyCode.H)) // "h" key turns histogram screen on/off histoWindowFlag = !histoWindowFlag; if (trackFlag) { if (Input.GetKeyDown(KeyCode.B)) // "b" key turns back projection on/off backprojWindowFlag = !backprojWindowFlag; if (Input.GetKeyDown(KeyCode.T)) // "t" key turns tracking openCV window on trackWindowFlag = !trackWindowFlag; // Move an external game object based on the ROI being tracked if (gameObjectTracker) ROIScreenToGameObject(rotatedBoxToTrack, gameObjectTracker); } if (Input.GetMouseButtonDown(1)) { // Right mouse button Debug.Log("Tracking off"); trackFlag = false; _mouseIsDown = false; } else if (Input.GetMouseButtonDown(0)) { // Left mouse button if (!_mouseIsDown) { _mouseDownPos = Input.mousePosition; trackFlag = false; } _mouseIsDown = true; } if (Input.GetMouseButtonUp(0)) { // Left mouse button is up // If mouse went from down to up, then update the region of interest using the box if (_mouseIsDown) { // Calculate the histogram for the selected region of interest (ROI) _rectToTrack = CheckROIBounds(ConvertRect2CvRect(MakePixelBox(_mouseDownPos, _mouseLastPos))); if (DisplayROIFlag) { // Draw the region of interest to track DrawROIBox(videoSourceImage); } // Use Hue/Saturation histogram (not just the Hue dimension) _histogramToTrack = CalculateHSVHistogram(GetROI(videoSourceImage, _rectToTrack)); // Use Hue channel histogram only //_histogramToTrack = CalculateOneChannelHistogram (GetROI (videoSourceImage, _rectToTrack), 0, 179); lastPosition = new CvPoint(Mathf.FloorToInt(_rectToTrack.X), Mathf.FloorToInt(_rectToTrack.Y)); InitializeKalmanFilter(); trackFlag = true; } _mouseIsDown = false; } }
/// <summary> /// Calculates bayesian probabilistic histograms /// </summary> /// <param name="src"></param> /// <param name="dst"></param> #else /// <summary> /// Calculates bayesian probabilistic histograms /// </summary> /// <param name="src"></param> /// <param name="dst"></param> #endif public static void CalcBayesianProb(CvHistogram[] src, CvHistogram[] dst) { Cv.CalcBayesianProb(src, dst); }
// Takes an image and calculates its histogram in HSV color space // Color images have 3 channels (4 if you count alpha?) // Webcam captures them in (R)ed, (G)reen, (B)lue. // Convert to (H)ue, (S)aturation (V)alue to get better separation for thresholding CvHistogram CalculateHSVHistogram(CvMat _image) { // Hue, Saturation, Value or HSV is a color model that describes colors (hue or tint) // in terms of their shade (saturation or amount of gray) // and their brightness (value or luminance). // For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255] // hue varies from 0 to 179, see cvtColor float hueMin = 0, hueMax = 179; float[] hueRanges = new float[2] { hueMin, hueMax }; // saturation varies from 0 (black-gray-white) to // 255 (pure spectrum color) float satMin = 0, satMax = 255; float[] saturationRanges = new float[2] { satMin, satMax }; float valMin = 0, valMax = 255; float[] valueRanges = new float[2] { valMin, valMax }; float[][] ranges = { hueRanges, saturationRanges, valueRanges }; // Note: You don't need to use all 3 channels for the histogram. int hueBins = 32; // Number of bins in the Hue histogram (more bins = narrower bins) int satBins = 32; // Number of bins in the Saturation histogram (more bins = narrower bins) int valueBins = 8; // Number of bins in the Value histogram (more bins = narrower bins) float maxValue = 0, minValue = 0; // Minimum and maximum value of calculated histogram // Number of bins per histogram channel // If we use all 3 channels (H, S, V) then the histogram will have 3 dimensions. int[] hist_size = new int[] { hueBins, satBins, valueBins }; CvHistogram hist = new CvHistogram(hist_size, HistogramFormat.Array, ranges, true); using (CvMat _imageHSV = ConvertToHSV(_image)) // Convert the image to HSV // We could keep the image in B, G, R, A if we wanted to. // Just split the channels into B, G, R planes 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 RGB, then it would split into R, G, B 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 IplImage[] hsvPlanes = { Cv.GetImage(imgH), Cv.GetImage(imgS), Cv.GetImage(imgV) }; hist.Calc(hsvPlanes, false, null); // Call hist function (no accumulatation, no mask) // Do we need to normalize?? hist.GetMinMaxValue(out minValue, out maxValue); // Scale the histogram to unity height hist.Normalize(_imageHSV.Width * _imageHSV.Height * hist.Dim * hueMax / maxValue); } return hist; // Return the histogram }
/// <summary> /// 一つのヒストグラムをもう一方のヒストグラムで割る (cvCalcProbDensity相当). /// </summary> /// <param name="hist1">一番目のヒストグラム(除数)</param> /// <param name="hist2">二番目のヒストグラム</param> /// <param name="dst_hist">出力ヒストグラム</param> #else /// <summary> /// Divides one histogram by another. /// </summary> /// <param name="hist1">first histogram (the divisor). </param> /// <param name="hist2">second histogram. </param> /// <param name="dst_hist">destination histogram. </param> #endif public static void CalcProbDensity(CvHistogram hist1, CvHistogram hist2, CvHistogram dst_hist) { Cv.CalcProbDensity(hist1, hist2, dst_hist); }
// Creates an image from a 2D Histogram (x axis = Hue, y axis = Saturation) void DrawHSHistogram(CvHistogram hist) { // Get the maximum and minimum values from the histogram float minValue, maxValue; hist.GetMinMaxValue(out minValue, out maxValue); int xBins = hist.Bins.GetDimSize(0); // Number of hue bins (x axis) int yBins = hist.Bins.GetDimSize(1); // Number of saturation bins (y axis) // Create an image to visualize the histogram int scaleHeight = 5, scaleWidth = 5; CvMat hist_img = new CvMat(yBins * scaleHeight, xBins * scaleWidth, TriColorMatrix); hist_img.Zero(); // Set all the pixels to black double binVal; int _intensity; for (int h = 0; h < xBins; h++) { for (int s = 0; s < yBins; s++) { binVal = Cv.QueryHistValue_2D(hist, h, s); _intensity = Cv.Round(binVal / maxValue * 255); // 0 to 255 // Draw a rectangle (h, s) to (h+1, s+1) (scaled by window size) // The pixel value is the color of the histogram value at bin (h, s) hist_img.Rectangle(Cv.Point(h * scaleWidth, s * scaleHeight), Cv.Point((h + 1) * scaleWidth - 1, (s + 1) * scaleHeight - 1), Cv.RGB(_intensity, _intensity, _intensity), Cv.FILLED); } } Cv.ShowImage("HS Histogram", hist_img); }
/// <summary> /// 一つのヒストグラムをもう一方のヒストグラムで割る (cvCalcProbDensity相当). /// </summary> /// <param name="hist1">一番目のヒストグラム(除数)</param> /// <param name="hist2">二番目のヒストグラム</param> /// <param name="dst_hist">出力ヒストグラム</param> /// <param name="scale">出力ヒストグラムのスケール係数</param> #else /// <summary> /// Divides one histogram by another. /// </summary> /// <param name="hist1">first histogram (the divisor). </param> /// <param name="hist2">second histogram. </param> /// <param name="dst_hist">destination histogram. </param> /// <param name="scale">scale factor for the destination histogram. </param> #endif public static void CalcProbDensity(CvHistogram hist1, CvHistogram hist2, CvHistogram dst_hist, double scale) { Cv.CalcProbDensity(hist1, hist2, dst_hist, scale); }