public Watershed() { // cvWatershed // マウスで円形のマーカー(シード領域)の中心を指定し,複数のマーカーを設定する. // このマーカを画像のgradientに沿って広げて行き,gradientの高い部分に出来る境界を元に領域を分割する. // 領域は,最初に指定したマーカーの数に分割される. // (2)画像の読み込み,マーカー画像の初期化,結果表示用画像領域の確保を行なう using (IplImage srcImg = new IplImage(Const.ImageGoryokaku, LoadMode.AnyDepth | LoadMode.AnyColor)) using (IplImage dstImg = srcImg.Clone()) using (IplImage dspImg = srcImg.Clone()) using (IplImage markers = new IplImage(srcImg.Size, BitDepth.S32, 1)) { markers.Zero(); // (3)入力画像を表示しシードコンポーネント指定のためのマウスイベントを登録する using (CvWindow wImage = new CvWindow("image", WindowMode.AutoSize)) { wImage.Image = srcImg; // クリックにより中心を指定し,円形のシード領域を設定する int seedNum = 0; wImage.OnMouseCallback += delegate(MouseEvent ev, int x, int y, MouseEvent flags) { if (ev == MouseEvent.LButtonDown) { seedNum++; CvPoint pt = new CvPoint(x, y); markers.Circle(pt, 20, CvScalar.ScalarAll(seedNum), Cv.FILLED, LineType.Link8, 0); dspImg.Circle(pt, 20, CvColor.White, 3, LineType.Link8, 0); wImage.Image = dspImg; } }; CvWindow.WaitKey(); } // (4)watershed分割を実行する Cv.Watershed(srcImg, markers); // (5)実行結果の画像中のwatershed境界(ピクセル値=-1)を結果表示用画像上に表示する for (int i = 0; i < markers.Height; i++) { for (int j = 0; j < markers.Width; j++) { int idx = (int)(markers.Get2D(i, j).Val0); if (idx == -1) { dstImg.Set2D(i, j, CvColor.Red); } } } using (CvWindow wDst = new CvWindow("watershed transform", WindowMode.AutoSize)) { wDst.Image = dstImg; CvWindow.WaitKey(); } } }
public bool Undistortion(IplImage src, out IplImage dst, int panoramaImageWidth) { dst = null; if (src == null) { return(false); } IplImage dstTemp = new IplImage(panoramaImageWidth, (int)Math.Max((panoramaImageWidth / 4 * (_r2 - _r1) / _r2), 1), BitDepth.U8, 3); bool isUpdate = false; if (isUpdate = (_inputSize != src.Size || _outputSize != dstTemp.Size)) { _inputSize = src.Size; _outputSize = dstTemp.Size; _pointDictionary.Clear(); } object lockobj = new object(); ParallelOptions opt = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }; Parallel.For(0, dstTemp.Height, opt, i => { IplImage patch = new IplImage(1, 1, BitDepth.U8, 3); for (int x = 0; x < dstTemp.Width; ++x) { if (isUpdate || _isUpdate) { lock (lockobj) { _pointDictionary[i * dstTemp.Width + x] = ConvertPolar(x, i); } } Cv.GetRectSubPix(src, patch, _pointDictionary[i * dstTemp.Width + x]); dstTemp.Set2D(dstTemp.Height - i - 1, dstTemp.Width - x - 1, patch.Get2D(0, 0)); } patch.Dispose(); }); _isUpdate = false; dst = dstTemp.Clone(); dstTemp.Dispose(); return(true); }
/// <summary> /// destで指定された画像の座標(x, y)に対して、patternで /// 指定された7セグメントのビットパターンを書き込む。 /// </summary> /// <param name="dest">パターンを書き込む画像</param> /// <param name="x">x座標始点</param> /// <param name="y">y座標始点</param> /// <param name="pattern">7セグメントのビットパターン</param> public void write(IplImage dest, int x, int y, byte pattern) { IplImage writeImage = create(pattern); for (int _y = 0; _y < segment[0].Height; _y++) { for (int _x = 0; _x < segment[0].Width; _x++) { CvScalar cs = writeImage.Get2D(_y, _x); dest.Set2D(y + _y, x + _x, cs); } } }
public Watershed() { using (var srcImg = new IplImage(FilePath.Image.Goryokaku, LoadMode.AnyDepth | LoadMode.AnyColor)) using (var dstImg = srcImg.Clone()) using (var dspImg = srcImg.Clone()) using (var markers = new IplImage(srcImg.Size, BitDepth.S32, 1)) { markers.Zero(); using (var window = new CvWindow("image", WindowMode.AutoSize)) { window.Image = srcImg; // Mouse event int seedNum = 0; window.OnMouseCallback += delegate(MouseEvent ev, int x, int y, MouseEvent flags) { if (ev == MouseEvent.LButtonDown) { seedNum++; CvPoint pt = new CvPoint(x, y); markers.Circle(pt, 20, CvScalar.ScalarAll(seedNum), Cv.FILLED, LineType.Link8, 0); dspImg.Circle(pt, 20, CvColor.White, 3, LineType.Link8, 0); window.Image = dspImg; } }; CvWindow.WaitKey(); } Cv.Watershed(srcImg, markers); // draws watershed for (int i = 0; i < markers.Height; i++) { for (int j = 0; j < markers.Width; j++) { int idx = (int)(markers.Get2D(i, j).Val0); if (idx == -1) { dstImg.Set2D(i, j, CvColor.Red); } } } using (CvWindow wDst = new CvWindow("watershed transform", WindowMode.AutoSize)) { wDst.Image = dstImg; CvWindow.WaitKey(); } } }
/// <summary> /// srcで指定されたマッチング対象の画像の座標(x, y)に対して、 /// 7セグメントのマッチングを行い、マッチング結果を7セグの /// ビットパターンとして返す。 /// </summary> /// <param name="src">マッチング対象の画像</param> /// <param name="x">x座標始点</param> /// <param name="y">y座標始点</param> /// <param name="threshold">マッチングに使用する閾値(0-100)</param> /// <returns>7セグメントのビットパターン</returns> public byte match(IplImage src, int x, int y, int threshold) { byte pattern = 0x00; for (int i = 0; i < SEGMENT_NUM; i++) { // TODO: segmentそれぞれに白ピクセル数を覚えさせておくと高速化できそう int samePixelNum = 0; int totalPixelNum = 0; for (int _y = 0; _y < segment[i].Height; _y++) { for (int _x = 0; _x < segment[i].Width; _x++) { CvScalar segmentPixel = segment[i].Get2D(_y, _x); if (segmentPixel.Val0 == 255 && segmentPixel.Val1 == 255 && segmentPixel.Val2 == 255 && segmentPixel.Val3 == 0) { CvScalar srcPixel = src.Get2D(y + _y, x + _x); // TODO: 応急処置 // (255, 0, 0, 0)の画像もあるみたい /*** * if (srcPixel.Val0 == 255 && * srcPixel.Val1 == 255 && * srcPixel.Val2 == 255 && * srcPixel.Val3 == 0) ***/ if (srcPixel.Val0 == 255 && srcPixel.Val1 == 0 && srcPixel.Val2 == 0 && srcPixel.Val3 == 0) { samePixelNum++; } totalPixelNum++; } } } // 白ピクセル部分全体に占める対象画像の白ピクセル数の割合を求める. // ある一定以上の割合であると当該セグメントを書き込む. if (((double)samePixelNum / totalPixelNum) * 100 >= threshold) { pattern |= (byte)(0x80 >> i); } } return(pattern); }
// Update is called once per frame void Update() { IplImage frame = Cv.QueryFrame(capture); imgBinary = new IplImage(frame.Size, BitDepth.U8, 1); imgLabel = new IplImage(frame.Size, BitDepth.F32, 1); imgRender = new IplImage(frame.Size, BitDepth.U8, 3); imgContour = new IplImage(frame.Size, BitDepth.U8, 3); imgPolygon = new IplImage(frame.Size, BitDepth.U8, 3); Color[] cols = new Color[texture.width * texture.height]; Cv.CvtColor(frame, imgBinary, ColorConversion.BgrToGray); Cv.Threshold(imgBinary, imgBinary, 100, 255, ThresholdType.Binary); CvBlobs blobs = new CvBlobs(); uint result = blobs.Label(imgBinary, imgLabel); foreach (KeyValuePair <uint, CvBlob> item in blobs) { CvBlob b = item.Value; //Console.WriteLine ("{0} | Centroid:{1} Area:{2}", item.Key, b.Centroid, b.Area); CvContourChainCode cc = b.Contour; cc.RenderContourChainCode(imgContour); CvContourPolygon polygon = cc.ConvertChainCodesToPolygon(); foreach (CvPoint p in polygon) { imgPolygon.Circle(p, 1, CvColor.Red, -1); } } blobs.RenderBlobs(imgLabel, frame, imgRender); for (int y = 0; y < texture.height; y++) { for (int x = 0; x < texture.width; x++) { CvColor col = imgRender.Get2D(y, x); cols[y * texture.width + x] = new Color(col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, 1.0f); } } // int t2 = System.Environment.TickCount; texture.SetPixels(cols); //int t3 = System.Environment.TickCount; //Debug.Log("t2-t1=" + (t2 - t1) + " t3-t2=" + (t3 - t2)); texture.Apply(); }
void RenderImagePlane() { IplImage frame = Cv.QueryFrame(capture); Color[] pixelArray = new Color[captureTexture.width * captureTexture.height]; for (int y = 0; y < captureTexture.height; y++) { for (int x = 0; x < captureTexture.width; x++) { CvColor tempColor = frame.Get2D(y, x); pixelArray[y * captureTexture.width + x] = new Color(tempColor.R / 255.0f, tempColor.G / 255.0f, tempColor.B / 255.0f, 1.0f); } } captureTexture.SetPixels(pixelArray); captureTexture.Apply(); renderer.material.mainTexture = captureTexture; }
// private IplImage Texture2DtoIplImage(Texture2D txtur) { int w = 320, h = 240; Color[] pixels; if (txtur != null) { pixels = txtur.GetPixels(); w = txtur.width; h = txtur.height; } else { pixels = new Color[w * h]; } //IplImage img = new IplImage(w,h,BitDepth.F32,1); IplImage img = Cv.CreateImage(new CvSize(w, h), BitDepth.U8, 3); for (int i = 0; i < h; i++) { //char ptr = img.ImageData+i*img.WidthStep; for (int j = 0; j < w; j++) { //ptr[3*j+2] = 255; CvScalar s = img.Get2D(i, j); s.Val0 = pixels[i * w + j].r; s.Val1 = pixels[i * w + j].g; s.Val2 = pixels[i * w + j].b; img.Set2D(i, j, s); //Color color = new Color(r / 255.0f, g / 255.0f, b / 255.0f); //videoTexture.SetPixel(j, height - i - 1, color); } } return(img); }