Changeset 24259
- Timestamp:
- 11/19/08 15:03:53 (5 years ago)
- Location:
- lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample
- Files:
-
- 32 modified
-
Program.cs (modified) (1 diff)
-
Sample/BoundingRect.cs (modified) (4 diffs)
-
Sample/CalibrateCamera.cs (modified) (4 diffs)
-
Sample/Capture.cs (modified) (1 diff)
-
Sample/Contour.cs (modified) (5 diffs)
-
Sample/ConvertToWriteableBitmap.cs (modified) (2 diffs)
-
Sample/CornerDetect.cs (modified) (1 diff)
-
Sample/DFT.cs (modified) (5 diffs)
-
Sample/Deraunay.cs (modified) (7 diffs)
-
Sample/DistTransform.cs (modified) (1 diff)
-
Sample/Edge.cs (modified) (2 diffs)
-
Sample/FaceDetect.cs (modified) (1 diff)
-
Sample/FileStorage.cs (modified) (10 diffs)
-
Sample/Histogram.cs (modified) (6 diffs)
-
Sample/HoughLines.cs (modified) (2 diffs)
-
Sample/Inpaint.cs (modified) (3 diffs)
-
Sample/KMeans.cs (modified) (3 diffs)
-
Sample/Kalman.cs (modified) (4 diffs)
-
Sample/MatTest.cs (modified) (1 diff)
-
Sample/Morphology.cs (modified) (1 diff)
-
Sample/OpticalFlowBM.cs (modified) (1 diff)
-
Sample/Perspective.cs (modified) (2 diffs)
-
Sample/PixelAccess.cs (modified) (1 diff)
-
Sample/PixelSampling.cs (modified) (3 diffs)
-
Sample/PyrMeanShiftFiltering.cs (modified) (1 diff)
-
Sample/PyrSegmentation.cs (modified) (2 diffs)
-
Sample/Resize.cs (modified) (1 diff)
-
Sample/SeqTest.cs (modified) (1 diff)
-
Sample/Snake.cs (modified) (1 diff)
-
Sample/Text.cs (modified) (3 diffs)
-
Sample/Threshold.cs (modified) (2 diffs)
-
Sample/Undistort.cs (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Program.cs
r24213 r24259 44 44 //Sample.Contour(); 45 45 // System.Drawing.Bitmapへの変換 46 Sample.ConvertToBitmap();46 //Sample.ConvertToBitmap(); 47 47 // System.Windows.Media.Imaging.WriteableBitmapへの変換 48 48 //Sample.ConvertToWriteableBitmap(); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/BoundingRect.cs
r23096 r24259 11 11 /// 点列を包含する矩形 12 12 /// </summary> 13 public static void BoundingRect() 14 { 13 public static void BoundingRect() { 15 14 // cvBoundingRect 16 15 // 点列を包含する矩形を求める … … 26 25 CvPoint[] points = new CvPoint[50]; 27 26 for (int i = 0; i < 50; i++) { 28 points[i] = new CvPoint() {27 points[i] = new CvPoint() { 29 28 X = (int)(rng.RandInt() % (img.Width / 2) + img.Width / 4), 30 29 Y = (int)(rng.RandInt() % (img.Height / 2) + img.Height / 4) … … 43 42 img.Circle(pt, 3, new CvColor(0, 255, 0), CV.CV_FILLED); 44 43 } 45 //*/ 44 //*/ 46 45 // (3)点列を包含する矩形を求めて描画する 47 46 CvRect rect = CV.BoundingRect(points); … … 55 54 } 56 55 } 57 -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/CalibrateCamera.cs
r23096 r24259 12 12 /// カメラキャリブレーション 13 13 /// </summary> 14 public static void CalibrateCamera() 15 { 14 public static void CalibrateCamera() { 16 15 const int IMAGE_NUM = 3; // 画像数 17 16 const int PAT_ROW = 7; // パターンの行数 … … 46 45 // (3)チェスボード(キャリブレーションパターン)のコーナー検出 47 46 int found_num = 0; 48 List<CvPoint2D32f> allCorners = new List<CvPoint2D32f>(ALL_POINTS); 47 List<CvPoint2D32f> allCorners = new List<CvPoint2D32f>(ALL_POINTS); 49 48 int[] p_count = new int[IMAGE_NUM]; 50 49 using (CvWindow window = new CvWindow("Calibration", WindowMode.AutoSize)) { … … 57 56 Debug.Print("ok"); 58 57 found_num++; 59 } else { 58 } 59 else { 60 60 Debug.Print("fail"); 61 61 } … … 101 101 img.Dispose(); 102 102 } 103 103 104 104 } 105 105 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Capture.cs
r21345 r24259 11 11 /// キャプチャした動画の再生 12 12 /// </summary> 13 public static void Capture() 14 { 13 public static void Capture() { 15 14 // AVIファイルからのキャプチャ 16 15 /* -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Contour.cs
r23096 r24259 11 11 /// 輪郭領域の面積と輪郭の長さ 12 12 /// </summary> 13 public static void Contour() 14 { 13 public static void Contour() { 15 14 // cvContourArea, cvArcLength 16 15 // 輪郭によって区切られた領域の面積と,輪郭の長さを求める … … 26 25 CvRNG rng = new CvRNG((ulong)DateTime.Now.Ticks); 27 26 double scale = rng.RandReal() + 0.5; 28 CvPoint pt0 = new CvPoint {27 CvPoint pt0 = new CvPoint { 29 28 X = (int)(Math.Cos(0) * SIZE / 4 * scale + SIZE / 2), 30 29 Y = (int)(Math.Sin(0) * SIZE / 4 * scale + SIZE / 2) … … 34 33 for (int i = 1; i < 20; i++) { 35 34 scale = rng.RandReal() + 0.5; 36 CvPoint pt1 = new CvPoint {35 CvPoint pt1 = new CvPoint { 37 36 X = (int)(Math.Cos(i * 2 * Math.PI / 20) * SIZE / 4 * scale + SIZE / 2), 38 37 Y = (int)(Math.Sin(i * 2 * Math.PI / 20) * SIZE / 4 * scale + SIZE / 2) … … 43 42 img.Circle(pt0, 3, CvColor.Green, CV.FILLED); 44 43 points.Push(pt0); 45 } 44 } 46 45 img.Line(pt0, points.GetElem<CvPoint>(0).Value, CvColor.Green, 2); 47 46 // (3)包含矩形,面積,長さを求める … … 50 49 double length = points.ArcLength(CvSlice.WholeSeq, 1); 51 50 // (4)結果を画像に書き込む 52 img.Rectangle( new CvPoint(rect.X, rect.Y), new CvPoint(rect.X + rect.Width, rect.Y + rect.Height), CvColor.Red, 2);51 img.Rectangle(new CvPoint(rect.X, rect.Y), new CvPoint(rect.X + rect.Width, rect.Y + rect.Height), CvColor.Red, 2); 53 52 string text_area = string.Format("Area: wrect={0}, contour={1}", rect.Width * rect.Height, area); 54 53 string text_length = string.Format("Length: rect={0}, contour={1}", 2 * (rect.Width + rect.Height), length); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/ConvertToWriteableBitmap.cs
r23005 r24259 15 15 /// System.Windows.Media.Imaging.WriteableBitmapへの変換 16 16 /// </summary> 17 public static void ConvertToWriteableBitmap() 18 { 17 public static void ConvertToWriteableBitmap() { 19 18 WriteableBitmap wb = null; 20 19 … … 31 30 // WPFのWindowに表示してみる 32 31 Image image = new Image() { Source = wb }; 33 Window window = new Window() {32 Window window = new Window() { 34 33 Title = "from IplImage to WriteableBitmap", 35 34 Width = wb.Width, 36 35 Height = wb.Height, 37 36 Content = image 38 }; 39 37 }; 38 40 39 Application app = new Application(); 41 40 app.Run(window); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/CornerDetect.cs
r23096 r24259 11 11 /// コーナーの検出 12 12 /// </summary> 13 public static void CornerDetect() 14 { 13 public static void CornerDetect() { 15 14 // cvGoodFeaturesToTrack, cvFindCornerSubPix 16 15 // 画像中のコーナー(特徴点)検出 17 16 18 int corner_count = 150; 19 17 int corner_count = 150; 18 20 19 using (IplImage dst_img1 = new IplImage(Const.IMAGE_LENNA, LoadMode.AnyColor | LoadMode.AnyDepth)) 21 20 using (IplImage dst_img2 = dst_img1.Clone()) -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/DFT.cs
r23213 r24259 11 11 /// 離散フーリエ変換 12 12 /// </summary> 13 public static void DFT() 14 { 13 public static void DFT() { 15 14 // cvDFT 16 15 // 離散フーリエ変換を用いて,振幅画像を生成する. 17 18 using (IplImage src_img = new IplImage(Const.IMAGE_GORYOKAKU, LoadMode.GrayScale)) 16 17 using (IplImage src_img = new IplImage(Const.IMAGE_GORYOKAKU, LoadMode.GrayScale)) 19 18 using (IplImage realInput = CV.CreateImage(src_img.Size, BitDepth.F64, 1)) 20 19 using (IplImage imaginaryInput = CV.CreateImage(src_img.Size, BitDepth.F64, 1)) 21 using (IplImage complexInput = CV.CreateImage(src_img.Size, BitDepth.F64, 2)) { 20 using (IplImage complexInput = CV.CreateImage(src_img.Size, BitDepth.F64, 2)) { 22 21 // (1)入力画像を実数配列にコピーし,虚数配列とマージして複素数平面を構成 23 22 CV.Scale(src_img, realInput, 1.0, 0.0); … … 27 26 int dft_M = CV.GetOptimalDFTSize(src_img.Height - 1); 28 27 int dft_N = CV.GetOptimalDFTSize(src_img.Width - 1); 29 using (CvMat dft_A = CV.CreateMat(dft_M, dft_N, MatrixType.F64C2)) 28 using (CvMat dft_A = CV.CreateMat(dft_M, dft_N, MatrixType.F64C2)) 30 29 using (IplImage image_Re = new IplImage(new CvSize(dft_N, dft_M), BitDepth.F64, 1)) 31 30 using (IplImage image_Im = new IplImage(new CvSize(dft_N, dft_M), BitDepth.F64, 1)) { … … 52 51 cvShiftDFT(image_Re, image_Re); 53 52 // (8)振幅画像のピクセル値が0.0-1.0に分布するようにスケーリング 54 double m, M; 53 double m, M; 55 54 CV.MinMaxLoc(image_Re, out m, out M); 56 55 CV.Scale(image_Re, image_Re, 1.0 / (M - m), 1.0 * (-m) / (M - m)); 57 using (CvWindow w_image = new CvWindow("Image", WindowMode.AutoSize, src_img))56 using (CvWindow w_image = new CvWindow("Image", WindowMode.AutoSize, src_img)) 58 57 using (CvWindow w_magnitude = new CvWindow("Magnitude", WindowMode.AutoSize, image_Re)) { 59 58 CV.WaitKey(0); … … 69 68 /// <param name="src_arr"></param> 70 69 /// <param name="dst_arr"></param> 71 private static void cvShiftDFT(CvArr src_arr, CvArr dst_arr) 72 { 70 private static void cvShiftDFT(CvArr src_arr, CvArr dst_arr) { 73 71 CvSize size = CV.GetSize(src_arr); 74 72 CvSize dst_size = CV.GetSize(dst_arr); … … 105 103 CV.Copy(q1, d3, null); 106 104 CV.Copy(q2, d4, null); 107 } else { /* インプレースモード */ 105 } 106 else { /* インプレースモード */ 108 107 CV.Copy(q3, tmp, null); 109 108 CV.Copy(q1, q3, null); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Deraunay.cs
r22624 r24259 11 11 /// ドロネー 12 12 /// </summary> 13 public static void Delaunay() 14 { 13 public static void Delaunay() { 15 14 CvRect rect = new CvRect(0, 0, 600, 600); 16 15 CvColor active_facet_color = new CvColor(255, 0, 0); … … 56 55 /// <param name="img"></param> 57 56 /// <param name="active_color"></param> 58 private static void locate_point(CvSubdiv2D subdiv, CvPoint2D32f fp, IplImage img, CvScalar active_color) 59 { 57 private static void locate_point(CvSubdiv2D subdiv, CvPoint2D32f fp, IplImage img, CvScalar active_color) { 60 58 CvSubdiv2DEdge e; 61 59 CvSubdiv2DEdge e0 = 0; 62 60 CvSubdiv2DPoint p = null; 63 61 64 subdiv.Locate(fp, out e0, out p);62 subdiv.Locate(fp, out e0, out p); 65 63 66 64 if (e0 != 0) { … … 82 80 /// <param name="delaunay_color"></param> 83 81 /// <param name="voronoi_color"></param> 84 private static void draw_subdiv(IplImage img, CvSubdiv2D subdiv, CvColor delaunay_color, CvColor voronoi_color) 85 { 82 private static void draw_subdiv(IplImage img, CvSubdiv2D subdiv, CvColor delaunay_color, CvColor voronoi_color) { 86 83 CvSeqReader reader = new CvSeqReader(); 87 84 int total = subdiv.Edges.Total; … … 108 105 /// <param name="edge"></param> 109 106 /// <param name="color"></param> 110 private static void draw_subdiv_edge(IplImage img, CvSubdiv2DEdge edge, CvScalar color) 111 { 107 private static void draw_subdiv_edge(IplImage img, CvSubdiv2DEdge edge, CvScalar color) { 112 108 CvSubdiv2DPoint org_pt = edge.EdgeOrg(); 113 109 CvSubdiv2DPoint dst_pt = edge.EdgeDst(); … … 129 125 /// <param name="subdiv"></param> 130 126 /// <param name="img"></param> 131 private static void paint_voronoi(CvSubdiv2D subdiv, IplImage img) 132 { 127 private static void paint_voronoi(CvSubdiv2D subdiv, IplImage img) { 133 128 CvSeqReader reader = new CvSeqReader(); 134 129 int total = subdiv.Edges.Total; … … 157 152 /// <param name="img"></param> 158 153 /// <param name="edge"></param> 159 private static void draw_subdiv_facet(IplImage img, CvSubdiv2DEdge edge) 160 { 154 private static void draw_subdiv_facet(IplImage img, CvSubdiv2DEdge edge) { 161 155 CvSubdiv2DEdge t = edge; 162 156 int count = 0; … … 196 190 /// <param name="fp"></param> 197 191 /// <param name="color"></param> 198 private static void draw_subdiv_point(IplImage img, CvPoint2D32f fp, CvColor color) 199 { 192 private static void draw_subdiv_point(IplImage img, CvPoint2D32f fp, CvColor color) { 200 193 img.Circle(fp, 3, color, CV.FILLED, LineType.AntiAlias, 0); 201 194 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/DistTransform.cs
r23096 r24259 11 11 /// 距離変換とその可視化 12 12 /// </summary> 13 public static void DistTransform() 14 { 13 public static void DistTransform() { 15 14 // cvDistTransform 16 15 // 入力画像に対して距離変換を行ない,結果を0-255に正規化し可視化する 17 16 18 17 // (1)画像を読み込み 19 using (IplImage src = new IplImage(Const.IMAGE_LENNA, LoadMode.GrayScale)) {20 if (src.Depth != BitDepth.U8) {18 using (IplImage src = new IplImage(Const.IMAGE_LENNA, LoadMode.GrayScale)) { 19 if (src.Depth != BitDepth.U8) { 21 20 throw new Exception("Invalid depth"); 22 21 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Edge.cs
r21480 r24259 11 11 /// エッジ検出 12 12 /// </summary> 13 public static void Edge() 14 { 13 public static void Edge() { 15 14 using (IplImage src = new IplImage(Const.IMAGE_LENNA, LoadMode.GrayScale)) 16 15 using (IplImage temp = new IplImage(src.Size, BitDepth.S16, 1)) 17 using (IplImage dst_sobel = new IplImage(src.Size, BitDepth.U8, 1)) 18 using (IplImage dst_laplace = new IplImage(src.Size, BitDepth.U8, 1)) 16 using (IplImage dst_sobel = new IplImage(src.Size, BitDepth.U8, 1)) 17 using (IplImage dst_laplace = new IplImage(src.Size, BitDepth.U8, 1)) 19 18 using (IplImage dst_canny = new IplImage(src.Size, BitDepth.U8, 1)) { 20 19 // Sobel … … 30 29 using (CvWindow w_sobel = new CvWindow("sobel", dst_sobel)) 31 30 using (CvWindow w_laplace = new CvWindow("laplace", dst_laplace)) 32 using (CvWindow w_canny = new CvWindow("canny", dst_canny)) { 31 using (CvWindow w_canny = new CvWindow("canny", dst_canny)) { 33 32 CvWindow.WaitKey(); 34 33 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/FaceDetect.cs
r23010 r24259 12 12 /// 顔の検出 13 13 /// </summary> 14 public static void FaceDetect() 15 { 14 public static void FaceDetect() { 16 15 // CvHaarClassifierCascade, cvHaarDetectObjects 17 16 // 顔を検出するためにHaar分類器のカスケードを用いる -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/FileStorage.cs
r23096 r24259 12 12 /// データのファイルストレージへの書き込み・読み込み 13 13 /// </summary> 14 public static void FileStorage() 15 { 14 public static void FileStorage() { 16 15 const string fileNameImage = "images.xml"; 17 16 const string fileNameSeq = "sequence.yml"; … … 31 30 /// </summary> 32 31 /// <param name="fileName">書きこむXML or YAMLファイル</param> 33 private static void SampleFileStorageWriteImage(string fileName) 34 { 32 private static void SampleFileStorageWriteImage(string fileName) { 35 33 // cvWrite, cvWriteComment 36 34 // IplImage構造体の情報をファイルに保存する … … 61 59 /// 画像データのファイルストレージからの読み込み 62 60 /// <param name="fileName">読み込むXML or YAMLファイル</param> 63 private static void SampleFileStorageReadImage(string fileName) 64 { 61 private static void SampleFileStorageReadImage(string fileName) { 65 62 IplImage color_img, gray_img; 66 63 // (1)ファイルを読み込む 67 using (CvFileStorage fs = new CvFileStorage(fileName, null, FileStorageMode.Read)){64 using (CvFileStorage fs = new CvFileStorage(fileName, null, FileStorageMode.Read)) { 68 65 CvFileNode node; 69 66 node = fs.GetFileNodeByName(null, "color_img"); … … 71 68 node = fs.GetFileNodeByName(null, "gray_img"); 72 69 gray_img = fs.Read<IplImage>(node); 73 } 70 } 74 71 // (2)ROI情報を取得し矩形を描いた後,解放 75 72 CvRect roi_color = color_img.GetROI(); … … 78 75 gray_img.ResetROI(); 79 76 color_img.Rectangle( 80 new CvPoint (roi_color.X, roi_color.Y),81 new CvPoint (roi_color.X + roi_color.Width, roi_color.Y + roi_color.Height),77 new CvPoint(roi_color.X, roi_color.Y), 78 new CvPoint(roi_color.X + roi_color.Width, roi_color.Y + roi_color.Height), 82 79 CvColor.Red 83 ); 80 ); 84 81 gray_img.Rectangle( 85 new CvPoint (roi_gray.X, roi_gray.Y),86 new CvPoint (roi_gray.X + roi_gray.Width, roi_gray.Y + roi_gray.Height),82 new CvPoint(roi_gray.X, roi_gray.Y), 83 new CvPoint(roi_gray.X + roi_gray.Width, roi_gray.Y + roi_gray.Height), 87 84 CvColor.Black 88 85 ); … … 90 87 using (CvWindow w_color = new CvWindow("Color Image", WindowMode.AutoSize, color_img)) 91 88 using (CvWindow w_gray = new CvWindow("Grayscale Image", WindowMode.AutoSize, gray_img)) { 92 CV.WaitKey (0);89 CV.WaitKey(0); 93 90 } 94 91 color_img.Dispose(); … … 100 97 /// </summary> 101 98 /// <param name="fileName">書きこむXML or YAMLファイル</param> 102 private static void SampleFileStorageWriteSeq(string fileName) 103 { 99 private static void SampleFileStorageWriteSeq(string fileName) { 104 100 // cvStartWriteStruct, cvEndWriteStruct 105 101 // 二つのエントリを持つマップのシーケンスをファイルに保存する … … 107 103 const int SIZE = 20; 108 104 CvRNG rng = new CvRNG((ulong)DateTime.Now.Ticks); 109 CvPoint[] pt = new CvPoint[SIZE]; 105 CvPoint[] pt = new CvPoint[SIZE]; 110 106 // (1)点列の作成 111 107 for (int i = 0; i < pt.Length; i++) { … … 134 130 /// </summary> 135 131 /// <param name="fileName">書きこむXML or YAMLファイル</param> 136 private static void SampleFileStorageReadSeq(string fileName) 137 { 132 private static void SampleFileStorageReadSeq(string fileName) { 138 133 // cvGetHashedKey, cvGetFileNode 139 134 // 二つのエントリを持つマップのシーケンスをファイルから読み込む … … 180 175 // (5)さらに低速だが,使いやすいバージョン 181 176 ///* 182 int x = fs.ReadIntByName(pt, "x", 0); 183 int y = fs.ReadIntByName(pt, "y", 0); 177 int x = fs.ReadIntByName(pt, "x", 0); 178 int y = fs.ReadIntByName(pt, "y", 0); 184 179 //*/ 185 180 // (6)データを表示し,次のシーケンスノードを取得 -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Histogram.cs
r23213 r24259 12 12 /// ヒストグラムの描画 13 13 /// </summary> 14 public static void Histogram() 15 { 14 public static void Histogram() { 16 15 // cvCalcHist 17 16 // コントラストや明度をいろいろ変えられるサンプル 18 17 19 18 const int HIST_SIZE = 64; 20 19 float[] range_0 = { 0, 256 }; 21 float[][] ranges = { range_0 }; 20 float[][] ranges = { range_0 }; 22 21 23 22 // 画像の読み込み … … 48 47 hist_img.Zero(); 49 48 }; 50 49 51 50 // トラックバーの作成 52 51 // (OpenCVでは現在位置にポインタを渡すことでトラックバーの位置の変化が取得できるが、 … … 69 68 /// <param name="brightness"></param> 70 69 /// <returns></returns> 71 private static byte[] _CalcLut(int contrast, int brightness) 72 { 70 private static byte[] _CalcLut(int contrast, int brightness) { 73 71 byte[] lut = new byte[256]; 74 72 /* … … 88 86 lut[i] = (byte)v; 89 87 } 90 } else { 88 } 89 else { 91 90 double delta = -128.0 * contrast / 100; 92 91 double a = (256.0 - delta * 2) / 255.0; … … 108 107 /// <param name="img"></param> 109 108 /// <param name="hist"></param> 110 private static void _CalcHist(IplImage img, CvHistogram hist) 111 { 109 private static void _CalcHist(IplImage img, CvHistogram hist) { 112 110 hist.Calc(img); 113 111 float min_value, max_value; … … 121 119 /// <param name="hist"></param> 122 120 /// <param name="hist_size"></param> 123 private static void _DrawHist(IplImage img, CvHistogram hist, int hist_size) 124 { 121 private static void _DrawHist(IplImage img, CvHistogram hist, int hist_size) { 125 122 img.Set(CvColor.White); 126 123 int bin_w = CV.Round((double)img.Width / hist_size); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/HoughLines.cs
r23096 r24259 11 11 /// ハフ変換による直線検出 12 12 /// </summary> 13 public static void HoughLines() 14 { 13 public static void HoughLines() { 15 14 // cvHoughLines2 16 15 // 標準的ハフ変換と確率的ハフ変換を指定して線(線分)の検出を行なう.サンプルコード内の各パラメータ値は処理例の画像に対してチューニングされている. 17 16 18 17 // (1)画像の読み込み 19 using (IplImage src_img_gray = new IplImage(Const.IMAGE_GORYOKAKU, LoadMode.GrayScale)) 18 using (IplImage src_img_gray = new IplImage(Const.IMAGE_GORYOKAKU, LoadMode.GrayScale)) 20 19 using (IplImage src_img_std = new IplImage(Const.IMAGE_GORYOKAKU, LoadMode.Color)) 21 20 using (IplImage src_img_prob = src_img_std.Clone()) { … … 24 23 using (CvMemStorage storage = new CvMemStorage()) { 25 24 // (3)標準的ハフ変換による線の検出と検出した線の描画 26 CvSeq lines = src_img_gray.HoughLines2(storage, HoughLinesMethod.Standard, 1, Math.PI /180, 50, 0, 0);25 CvSeq lines = src_img_gray.HoughLines2(storage, HoughLinesMethod.Standard, 1, Math.PI / 180, 50, 0, 0); 27 26 int limit = Math.Min(lines.Total, 10); 28 for (int i = 0; i < limit; i++) unsafe {29 float* line = (float*)lines.GetElem<IntPtr>(i).Value.ToPointer(); // ポインタで取得し、float*にキャスト. ポインタ使わずに済む方法はないものか・・・30 float rho = line[0];31 float theta = line[1];32 double a = Math.Cos(theta);33 double b = Math.Sin(theta);34 double x0 = a * rho;35 double y0 = b * rho;36 CvPoint pt1 = new CvPoint { X = CV.Round(x0 + 1000 * (-b)), Y = CV.Round(y0 + 1000 * (a)) };37 CvPoint pt2 = new CvPoint { X = CV.Round(x0 - 1000 * (-b)), Y = CV.Round(y0 - 1000 * (a)) };38 src_img_std.Line(pt1, pt2, CvColor.Red, 3, LineType.AntiAlias, 0);39 }27 for (int i = 0; i < limit; i++) unsafe { 28 float* line = (float*)lines.GetElem<IntPtr>(i).Value.ToPointer(); // ポインタで取得し、float*にキャスト. ポインタ使わずに済む方法はないものか・・・ 29 float rho = line[0]; 30 float theta = line[1]; 31 double a = Math.Cos(theta); 32 double b = Math.Sin(theta); 33 double x0 = a * rho; 34 double y0 = b * rho; 35 CvPoint pt1 = new CvPoint { X = CV.Round(x0 + 1000 * (-b)), Y = CV.Round(y0 + 1000 * (a)) }; 36 CvPoint pt2 = new CvPoint { X = CV.Round(x0 - 1000 * (-b)), Y = CV.Round(y0 - 1000 * (a)) }; 37 src_img_std.Line(pt1, pt2, CvColor.Red, 3, LineType.AntiAlias, 0); 38 } 40 39 // (4)確率的ハフ変換による線分の検出と検出した線分の描画 41 40 lines = null; 42 lines = src_img_gray.HoughLines2(storage, HoughLinesMethod.Probabilistic, 1, Math.PI /180, 50, 50, 10);43 for (int i = 0; i < lines.Total; i++) unsafe {44 CvPoint* point = (CvPoint*)lines.GetElem<IntPtr>(i).Value.ToPointer();45 src_img_prob.Line(point[0], point[1], CvColor.Red, 3, LineType.AntiAlias, 0);46 }41 lines = src_img_gray.HoughLines2(storage, HoughLinesMethod.Probabilistic, 1, Math.PI / 180, 50, 50, 10); 42 for (int i = 0; i < lines.Total; i++) unsafe { 43 CvPoint* point = (CvPoint*)lines.GetElem<IntPtr>(i).Value.ToPointer(); 44 src_img_prob.Line(point[0], point[1], CvColor.Red, 3, LineType.AntiAlias, 0); 45 } 47 46 } 48 47 // (5)検出結果表示用のウィンドウを確保し表示する 49 48 using (CvWindow w_std = new CvWindow("Hough_line_standard", WindowMode.AutoSize, src_img_std)) 50 using (CvWindow w_prob = new CvWindow("Hough_line_probabilistic", WindowMode.AutoSize, src_img_prob)) { 49 using (CvWindow w_prob = new CvWindow("Hough_line_probabilistic", WindowMode.AutoSize, src_img_prob)) { 51 50 CvWindow.WaitKey(0); 52 51 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Inpaint.cs
r23096 r24259 12 12 /// 不要オブジェクトの除去 13 13 /// </summary> 14 public static void Inpaint() 15 { 14 public static void Inpaint() { 16 15 // cvInpaint 17 16 // 画像の不要な文字列部分に対するマスク画像を指定して文字列を除去する 18 17 19 Console.WriteLine( 18 Console.WriteLine( 20 19 "Hot keys: \n" + 21 20 "\tESC - quit the program\n" + … … 29 28 using (IplImage img0 = new IplImage(Const.IMAGE_FRUITS, LoadMode.AnyDepth | LoadMode.AnyColor)) { 30 29 // お絵かき用の画像を確保(マスク) 31 using (IplImage img = img0.Clone()) 30 using (IplImage img = img0.Clone()) 32 31 using (IplImage inpaint_mask = new IplImage(img0.Size, BitDepth.U8, 1)) 33 32 // Inpaintの出力先画像を確保 … … 36 35 inpaint_mask.Zero(); 37 36 38 using (CvWindow w_image = new CvWindow( "image", WindowMode.AutoSize, img)){37 using (CvWindow w_image = new CvWindow("image", WindowMode.AutoSize, img)) { 39 38 40 39 // マウスイベントの処理 41 40 CvPoint prev_pt = new CvPoint(-1, -1); 42 w_image.OnMouseCallback += delegate(MouseEvent ev, int x, int y, MouseEvent flags) {43 if ( ev == MouseEvent.LButtonUp || (flags & MouseEvent.FlagLButton) == 0 ){41 w_image.OnMouseCallback += delegate(MouseEvent ev, int x, int y, MouseEvent flags) { 42 if (ev == MouseEvent.LButtonUp || (flags & MouseEvent.FlagLButton) == 0) { 44 43 prev_pt = new CvPoint(-1, -1); 45 }else if( ev == MouseEvent.LButtonDown ){ 44 } 45 else if (ev == MouseEvent.LButtonDown) { 46 46 prev_pt = new CvPoint(x, y); 47 }else if( ev == MouseEvent.MouseMove && (flags & MouseEvent.FlagLButton) != 0 ){ 48 CvPoint pt = new CvPoint(x,y); 49 if( prev_pt.X < 0 ){ 47 } 48 else if (ev == MouseEvent.MouseMove && (flags & MouseEvent.FlagLButton) != 0) { 49 CvPoint pt = new CvPoint(x, y); 50 if (prev_pt.X < 0) { 50 51 prev_pt = pt; 51 52 } 52 inpaint_mask.Line( prev_pt, pt, CvColor.White, 5, LineType.AntiAlias, 0);53 img.Line( prev_pt, pt, CvColor.White, 5, LineType.AntiAlias, 0);53 inpaint_mask.Line(prev_pt, pt, CvColor.White, 5, LineType.AntiAlias, 0); 54 img.Line(prev_pt, pt, CvColor.White, 5, LineType.AntiAlias, 0); 54 55 prev_pt = pt; 55 w_image.ShowImage( img);56 w_image.ShowImage(img); 56 57 } 57 58 }; 58 59 59 60 for (; ; ) { 60 switch ( CvWindow.WaitKey(0)){61 case 27: // ESCキーで終了62 return;63 case 'r': // 原画像を復元64 inpaint_mask.Zero();65 img0.Copy(img);66 w_image.ShowImage(img);67 break;68 case 'i': // Inpaintの実行69 case '\r':70 CvWindow w_inpaint = new CvWindow("inpainted image", WindowMode.AutoSize);71 img.Inpaint(inpaint_mask, inpainted, 3, InpaintMethod.Telea);72 w_inpaint.ShowImage(inpainted);73 break;74 case 's': // 画像の保存75 string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);76 img0.SaveImage(Path.Combine(desktop, "original.png"));77 inpaint_mask.SaveImage(Path.Combine(desktop, "mask.png"));78 img.SaveImage(Path.Combine(desktop, "original+mask.png"));79 inpainted.SaveImage(Path.Combine(desktop, "inpainted.png"));80 break;61 switch (CvWindow.WaitKey(0)) { 62 case 27: // ESCキーで終了 63 return; 64 case 'r': // 原画像を復元 65 inpaint_mask.Zero(); 66 img0.Copy(img); 67 w_image.ShowImage(img); 68 break; 69 case 'i': // Inpaintの実行 70 case '\r': 71 CvWindow w_inpaint = new CvWindow("inpainted image", WindowMode.AutoSize); 72 img.Inpaint(inpaint_mask, inpainted, 3, InpaintMethod.Telea); 73 w_inpaint.ShowImage(inpainted); 74 break; 75 case 's': // 画像の保存 76 string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 77 img0.SaveImage(Path.Combine(desktop, "original.png")); 78 inpaint_mask.SaveImage(Path.Combine(desktop, "mask.png")); 79 img.SaveImage(Path.Combine(desktop, "original+mask.png")); 80 inpainted.SaveImage(Path.Combine(desktop, "inpainted.png")); 81 break; 81 82 } 82 83 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/KMeans.cs
r23096 r24259 11 11 /// クラスタリングによる減色処理 12 12 /// </summary> 13 public static void KMeans() 14 { 13 public static void KMeans() { 15 14 // cvKMeans2 16 15 // k-means法によるクラスタリングを利用して,非常に単純な減色を行う … … 18 17 // クラスタ数。この値を変えると色数が変わる 19 18 const int MAX_CLUSTERS = 32; 20 19 21 20 // (1)画像を読み込む 22 21 using (IplImage src_img = CV.LoadImage(Const.IMAGE_LENNA, LoadMode.Color)) … … 24 23 int size = src_img.Width * src_img.Height; 25 24 using (CvMat color = CV.CreateMat(MAX_CLUSTERS, 1, MatrixType.F32C3)) 26 using (CvMat count = CV.CreateMat(MAX_CLUSTERS, 1, MatrixType.S32C1)) 25 using (CvMat count = CV.CreateMat(MAX_CLUSTERS, 1, MatrixType.S32C1)) 27 26 using (CvMat clusters = CV.CreateMat(size, 1, MatrixType.S32C1)) 28 27 using (CvMat points = CV.CreateMat(size, 1, MatrixType.F32C3)) { -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Kalman.cs
r23096 r24259 15 15 /// <param name="angle"></param> 16 16 /// <returns></returns> 17 private static CvPoint CalcPoint(IplImage img, float angle) 18 { 17 private static CvPoint CalcPoint(IplImage img, float angle) { 19 18 return new CvPoint { 20 19 X = (int)Math.Round(img.Width / 2.0 + img.Width / 3.0 * Math.Cos(angle)), … … 29 28 /// <param name="color"></param> 30 29 /// <param name="d"></param> 31 private static void DrawCross(IplImage img, CvPoint center, CvColor color, int d) 32 { 30 private static void DrawCross(IplImage img, CvPoint center, CvColor color, int d) { 33 31 img.Line(center.X - d, center.Y - d, center.X + d, center.Y + d, color, 1, 0); 34 32 img.Line(center.X + d, center.Y - d, center.X - d, center.Y + d, color, 1, 0); … … 38 36 /// カルマンフィルタ 39 37 /// </summary> 40 public static unsafe void Kalman() 41 { 38 public static unsafe void Kalman() { 42 39 // cvKalmanPredict, cvKalmanCorrect 43 40 // カルマンフィルタを用いて回転する点を追跡する 44 41 45 42 /* 行列データ */ 46 float[] A = new float[] { 1, 1, 0, 1 }; 43 float[] A = new float[] { 1, 1, 0, 1 }; 47 44 48 45 using (IplImage img = new IplImage(500, 500, BitDepth.U8, 3)) … … 92 89 DrawCross(img, predict_pt, CvColor.Green, 3); 93 90 img.Line(state_pt, measurement_pt, new CvColor(255, 0, 0), 3, LineType.AntiAlias, 0); 94 img.Line(state_pt, predict_pt, new CvColor(255, 255, 0), 3, LineType.AntiAlias, 0); 91 img.Line(state_pt, predict_pt, new CvColor(255, 255, 0), 3, LineType.AntiAlias, 0); 95 92 96 93 /* カルマンフィルタ状態を修正 */ -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/MatTest.cs
r22624 r24259 11 11 /// 行列演算のテスト 12 12 /// </summary> 13 public static void MatTest() 14 { 13 public static void MatTest() { 15 14 // 行列aとbを初期化 16 15 // aはオーソドックスに1次元配列で元データを指定 -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Morphology.cs
r22624 r24259 11 11 /// モルフォロジー変換 12 12 /// </summary> 13 public static void Morphology() 14 { 13 public static void Morphology() { 15 14 // cvMorphologyEx 16 15 // 構造要素を指定して,様々なモルフォロジー演算を行なう 17 16 18 17 //(1)画像の読み込み,演算結果画像領域の確保を行なう 19 using (IplImage src_img = new IplImage(Const.IMAGE_LENNA, LoadMode.AnyDepth | LoadMode.AnyColor)) 18 using (IplImage src_img = new IplImage(Const.IMAGE_LENNA, LoadMode.AnyDepth | LoadMode.AnyColor)) 20 19 using (IplImage dst_img_dilate = src_img.Clone()) 21 20 using (IplImage dst_img_erode = src_img.Clone()) -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/OpticalFlowBM.cs
r22624 r24259 11 11 /// ブロックマッチングによるオプティカルフローの計算 12 12 /// </summary> 13 public static void OpticalFlowBM() 14 { 13 public static void OpticalFlowBM() { 15 14 // cvCalcOpticalFlowBM 16 15 // ブロックマッチングによるオプティカルフローの計算 -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Perspective.cs
r22624 r24259 11 11 /// 画像の透視投影変換 12 12 /// </summary> 13 public static void Perspective() 14 { 13 public static void Perspective() { 15 14 // cvGetPerspectiveTransform + cvWarpPerspective 16 15 // 画像上の4点対応より透視投影変換行列を計算し,その行列を用いて画像全体の透視投影変換を行う. … … 33 32 using (CvMat map_matrix = CV.GetPerspectiveTransform(src_pnt, dst_pnt)) { 34 33 // (3)指定されたアフィン行列により,cvWarpAffineを用いて画像を回転させる 35 CV.WarpPerspective(src_img, dst_img, map_matrix, Interpolation.Linear | Interpolation.FillOutliers, CvScalar.ScalarAll(100)); 34 CV.WarpPerspective(src_img, dst_img, map_matrix, Interpolation.Linear | Interpolation.FillOutliers, CvScalar.ScalarAll(100)); 36 35 // (4)結果を表示する 37 36 using (CvWindow w_src = new CvWindow("src", src_img)) -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/PixelAccess.cs
r23096 r24259 12 12 /// ピクセルデータへの直接アクセス 13 13 /// </summary> 14 public static void PixelAccess() 15 { 14 public static void PixelAccess() { 16 15 // IplImage 17 16 // 8ビット3チャンネルカラー画像を読み込み,ピクセルデータを変更する -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/PixelSampling.cs
r22624 r24259 11 11 /// ピクセルサンプリング 12 12 /// </summary> 13 public static void PixelSampling() 14 { 13 public static void PixelSampling() { 15 14 // 並進移動のためのピクセルサンプリング cvGetRectSubPix 16 15 … … 37 36 // 回転移動のためのピクセルサンプリング cvGetQuadrangleSubPix 38 37 39 const int angle = 45; 38 const int angle = 45; 40 39 // (1)画像の読み込み,出力用画像領域の確保を行なう 41 40 using (IplImage src_img = new IplImage(Const.IMAGE_LENNA, LoadMode.AnyDepth | LoadMode.AnyColor)) 42 using (IplImage dst_img = src_img.Clone()) {41 using (IplImage dst_img = src_img.Clone()) { 43 42 // (2)回転のための行列(アフィン行列)要素を設定し,CvMat行列Mを初期化する 44 43 float[] m = new float[6]; … … 49 48 m[4] = m[0]; 50 49 m[5] = src_img.Height * 0.5f; 51 using (CvMat mat = new CvMat(2, 3, MatrixType.F32C1, m)) {50 using (CvMat mat = new CvMat(2, 3, MatrixType.F32C1, m)) { 52 51 // (3)指定された回転行列により,GetQuadrangleSubPixを用いて画像全体を回転させる 53 52 CV.GetQuadrangleSubPix(src_img, dst_img, mat); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/PyrMeanShiftFiltering.cs
r22624 r24259 11 11 /// 平均値シフト法による画像のセグメント化 12 12 /// </summary> 13 public static void PyrMeanShiftFiltering() 14 { 13 public static void PyrMeanShiftFiltering() { 15 14 // cvPyrMeanShiftFiltering 16 15 // 平均値シフト法による画像のセグメント化を行う -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/PyrSegmentation.cs
r22624 r24259 11 11 /// 画像ピラミッドを用いた画像の領域分割 12 12 /// </summary> 13 public static void PyrSegmentation() 14 { 13 public static void PyrSegmentation() { 15 14 // cvPyrSegmentation 16 15 // レベルを指定して画像ピラミッドを作成し,その情報を用いて画像のセグメント化を行なう. 17 16 18 17 const double THRESHOLD1 = 255.0; 19 const double THRESHOLD2 = 50.0; ;18 const double THRESHOLD2 = 50.0; ; 20 19 21 20 // (1)画像の読み込み … … 29 28 X = 0, 30 29 Y = 0, 31 Width = src_img.Width & -(1 << (level +1)),32 Height = src_img.Height & -(1 << (level +1))30 Width = src_img.Width & -(1 << (level + 1)), 31 Height = src_img.Height & -(1 << (level + 1)) 33 32 }; 34 33 src_img.ROI = roi; 35 34 // (3)分割結果画像出力用の画像領域を確保し,領域分割を実行 36 35 dst_img[level] = src_img.Clone(); 37 CV.PyrSegmentation(src_img, dst_img[level], level +1, THRESHOLD1, THRESHOLD2);36 CV.PyrSegmentation(src_img, dst_img[level], level + 1, THRESHOLD1, THRESHOLD2); 38 37 } 39 38 -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Resize.cs
r22624 r24259 11 11 /// 画像のサイズ変更 12 12 /// </summary> 13 public static void Resize() 14 { 13 public static void Resize() { 15 14 // cvResize 16 15 // 指定した出力画像サイズに合うように、入力画像のサイズを変更し出力する. -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/SeqTest.cs
r21039 r24259 11 11 /// CvSeqのテスト 12 12 /// </summary> 13 unsafe public static void SeqTest() 14 { 13 unsafe public static void SeqTest() { 15 14 using (CvMemStorage storage = new CvMemStorage(0)) { 16 15 CvSeq seq = new CvSeq(SeqType.EltypeS32C1, CvSeq.SizeOf, sizeof(int), storage); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Snake.cs
r21039 r24259 11 11 /// 輪郭検出 12 12 /// </summary> 13 public static void Snake() 14 { 13 public static void Snake() { 15 14 using (IplImage src = new IplImage(Const.IMAGE_CAKE, LoadMode.GrayScale)) 16 15 using (IplImage dst = new IplImage(src.Size, BitDepth.U8, 3)) { -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Text.cs
r22624 r24259 11 11 /// テキストの描画 12 12 /// </summary> 13 public static void Text() 14 { 13 public static void Text() { 15 14 // cvInitFont, cvPutText 16 15 // フォントを初期化して,テキストを描画する 17 16 18 17 List<FontFace> font_face = new List<FontFace>( 19 18 (FontFace[])Enum.GetValues(typeof(FontFace)) … … 27 26 CvFont[] font = new CvFont[font_face.Count * 2]; 28 27 for (int i = 0; i < font.Length; i += 2) { 29 CV.InitFont(out font[i], font_face[i /2], 1.0, 1.0);30 CV.InitFont(out font[i + 1], font_face[i /2] | FontFace.Italic, 1.0, 1.0);28 CV.InitFont(out font[i], font_face[i / 2], 1.0, 1.0); 29 CV.InitFont(out font[i + 1], font_face[i / 2] | FontFace.Italic, 1.0, 1.0); 31 30 } 32 31 // (3)フォントを指定して,テキストを描画する … … 34 33 for (int i = 0; i < font.Length; i++) { 35 34 uint irandom = CV.RandInt(rng); 36 CvColor rcolor = new CvColor( (byte)(irandom & 255), (byte)((irandom >> 8) & 255), (byte)((irandom >> 16) & 255));35 CvColor rcolor = new CvColor((byte)(irandom & 255), (byte)((irandom >> 8) & 255), (byte)((irandom >> 16) & 255)); 37 36 CV.PutText(img, "OpenCV sample code", new CvPoint(15, (i + 1) * 30), font[i], rcolor); 38 37 } -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Threshold.cs
r23213 r24259 11 11 /// 2値化 12 12 /// </summary> 13 public static void Threshold() 14 { 13 public static void Threshold() { 15 14 using (IplImage src = new IplImage(Const.IMAGE_LENNA, LoadMode.Color)) 16 15 using (IplImage src_gray = new IplImage(src.Size, BitDepth.U8, 1)) … … 20 19 src_gray.Smooth(src_gray, SmoothType.Gaussian, 5); 21 20 int threshold = 90; 22 w.CreateTrackbar("threshold", threshold, 255, delegate(int pos) { 23 src_gray.Threshold(dst, pos, 255, ThresholdType.Binary); 21 w.CreateTrackbar("threshold", threshold, 255, delegate(int pos) { 22 src_gray.Threshold(dst, pos, 255, ThresholdType.Binary); 24 23 w.Image = dst; 25 24 }); -
lang/cpluspluscli/OpenCvSharp/sample/OpenCvSharpSample/Sample/Undistort.cs
r23096 r24259 11 11 /// 歪み補正 12 12 /// </summary> 13 public static void Undistort() 14 { 13 public static void Undistort() { 15 14 // cvUndistort2 16 15 // キャリブレーションデータを利用して,歪みを補正する … … 18 17 // (1)補正対象となる画像の読み込み 19 18 using (IplImage src_img = new IplImage(Const.IMAGE_DISTORTION, LoadMode.Color)) 20 using (IplImage dst_img = src_img.Clone()) {19 using (IplImage dst_img = src_img.Clone()) { 21 20 22 21 // (2)パラメータファイルの読み込み … … 34 33 // (4)画像を表示,キーが押されたときに終了 35 34 using (CvWindow w1 = new CvWindow("Distortion", WindowMode.AutoSize, src_img)) 36 using (CvWindow w2 = new CvWindow("Undistortion", WindowMode.AutoSize, dst_img)) {35 using (CvWindow w2 = new CvWindow("Undistortion", WindowMode.AutoSize, dst_img)) { 37 36 CvWindow.WaitKey(0); 38 37 }
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)