public void homloop(object sender, EventArgs e) { image = Cv.QueryFrame(capture); homography homl = new homography(); double[] A = new double[]{ Properties.Settings.Default.X1, Properties.Settings.Default.Y1, Properties.Settings.Default.X2, Properties.Settings.Default.Y2, Properties.Settings.Default.X3, Properties.Settings.Default.Y3, Properties.Settings.Default.X4, Properties.Settings.Default.Y4 }; // 変換先の頂点の座標 double[] B = new double[]{ 0, 0, 0, 720, 960, 720, 960, 0 }; IplImage homed1 = Cv.CreateImage(new CvSize(image.Width, image.Height), BitDepth.U8, 3); homed1 = homl.hom(image, A, B); Bitmap homedb = BitmapConverter.ToBitmap(homed1); pictureBox5.Image = homedb; double H1 = Decimal.ToDouble(Properties.Settings.Default.ext_H1); double S1 = Decimal.ToDouble(Properties.Settings.Default.ext_S1); double V1 = Decimal.ToDouble(Properties.Settings.Default.ext_V1); double H2 = Decimal.ToDouble(Properties.Settings.Default.ext_H2); double S2 = Decimal.ToDouble(Properties.Settings.Default.ext_S2); double V2 = Decimal.ToDouble(Properties.Settings.Default.ext_V2); label1.Text = timer.Elapsed.ToString(); IplImage imgTracking = Cv.CreateImage(new CvSize(image.Width, image.Height), BitDepth.U8, 3); Cv.Zero(imgTracking); IplImage imgHSV = Cv.CreateImage(homed1.Size, BitDepth.U8, 3); Cv.CvtColor(homed1, imgHSV, ColorConversion.BgrToHsv); IplImage imgTo = Cv.CreateImage(new CvSize(imgHSV.Width, imgHSV.Height), BitDepth.U8, 1); //指定色を抽出 Cv.InRangeS(imgHSV, new CvScalar(H1, S1, V1), new CvScalar(H2, S2, V2), imgTo); if(Properties.Settings.Default.Filter1 == true) { Cv.Smooth(imgTo, imgTo, SmoothType.Median, 19, 19); } //ディスプレイの高さ int h = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height; //ディスプレイの幅 int w = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width; IplImage imgDispray = Cv.CreateImage(new CvSize(w, h), BitDepth.U8, 1); Cv.Resize(imgTo, imgDispray); CvMoments moments = new CvMoments(imgDispray, false); Bitmap imgToB = BitmapConverter.ToBitmap(imgDispray); pictureBox3.Image = imgToB; //指定色の面積取得 double area = Cv.GetCentralMoment(moments, 0, 0); double moments01 = Cv.GetSpatialMoment(moments, 0, 1); double moments10 = Cv.GetSpatialMoment(moments, 1, 0); //重心座標取得 int posX = (int)(moments10 / area); int posY = (int)(moments01 / area); if ((PastPoint.X != posX) || (PastPoint.Y != posY)) { if (MyStopWatch.IsRunning == true) { MyStopWatch.Stop(); } float nowX = Math.Abs((float)(posX - PastPoint.X)); //X成分の距離 //移動距離 float nowY = Math.Abs((float)(posY - PastPoint.Y)); //Y成分の距離 float nowXY = (float)Math.Sqrt((double)((nowX * nowX) + (nowY * nowY))); float MouseSpeed = (nowXY / (float)(MyStopWatch.ElapsedMilliseconds)); PastPoint = new Point(posX, posY); label2.Text = "移動距離X" + nowX.ToString(); label3.Text = "移動距離Y" + nowY.ToString(); label4.Text = "面積" + area.ToString(); label5.Text = "重心X" + posX.ToString(); label6.Text = "重心Y" + posY.ToString(); label7.Text = "カーソル速度" + MouseSpeed.ToString(); MyStopWatch.Restart(); //TopMost = true; if(posX < 0) { posX = 480; } if(posY < 0) { posY = 360; } //位置が0でなく、移動速度が0.4~1.6pixel/msec if (PastPoint.X >= 0 && PastPoint.Y >= 0 && posX >= 0 && posY >= 0 && MouseSpeed > 0.4 && MouseSpeed < 1.6) //0.4-1.6 { Graphics g = pictureBox1.CreateGraphics(); //描画定義 writeLog("線を描画しています"); Pen pen = new Pen(Color.Aqua); //ペン色 pen.Width = 5; //ペン太さ g.DrawLine(pen, sx1, sy1, posX, posY); sx1 = posX; sy1 = posY; PastPoint = new Point(posX, posY); //ug.Dispose(); aiu = 0; Invalidate(); } if (posY > 720 && MouseSpeed < 2.0 && aiu == 0) //2.0- { writeLog("ページを送ります"); //this.Hide(); SendKeys.Send("{RIGHT}"); aiu = 1; Invalidate(); } if (posY < 240 && MouseSpeed < 2.0 && aiu == 0) { writeLog("ページを戻します"); //this.Hide(); SendKeys.Send("{LEFT}"); aiu = 1; Invalidate(); } sx1 = posX; sy1 = posY; } }
private void uun(object sender, EventArgs e) { t.Stop(); writeLog("タイマーt停止"); t1.Stop(); writeLog("タイマーt1停止"); //using (var cap = Cv.CreateCameraCapture(0)) // カメラのキャプチャ //{ //IplImage im = new IplImage(); // カメラ画像格納用の変数 //while (Cv.WaitKey(1) == -1) // 任意のキーが入力されるまでカメラ映像を表示 //{ // im = Cv.QueryFrame(capture); // カメラからフレーム(画像)を取得 // Cv.ShowImage("Test", im); // カメラ映像の表示 // //Bitmap iplim = BitmapConverter.ToBitmap(im); // //pictureBox2.Image = iplim; //} //} //this.Focus(); image = Cv.QueryFrame(capture); //撮影 Cv.ReleaseImage(image); image = Cv.QueryFrame(capture); writeLog("撮影し、imageに格納しました"); timer.Start(); writeLog("タイマーtimer開始"); Bitmap myBitmap = BitmapConverter.ToBitmap(image); pictureBox2.Image = myBitmap; writeLog("imageをBitmap化、右上のボックスに表示します"); IplImage srcImg = BitmapConverter.ToIplImage(myBitmap); IplImage srcImgGray = new IplImage(srcImg.Size, BitDepth.U8, 1); IplImage tmpImg = new IplImage(srcImg.Size, BitDepth.U8, 1); if(Properties.Settings.Default.autoc == true) { CvMemStorage storage = new CvMemStorage(0); Cv.CvtColor(srcImg, srcImgGray, ColorConversion.BgrToGray); //画像の二値化と輪郭の検出 Cv.Threshold(srcImgGray, tmpImg, 100, 255, ThresholdType.Binary); // Cv.Threshold(srcImgGray,tmpImg, 0, 255, ThresholdType.Otsu); Bitmap srcimageG = BitmapConverter.ToBitmap(tmpImg); pictureBox4.Image = srcimageG; CvSeq<CvPoint> contours; //輪郭シーケンスを定義 Cv.FindContours(tmpImg, storage, out contours,CvContour.SizeOf,ContourRetrieval.Tree,ContourChain.ApproxSimple); contours = Cv.ApproxPoly(contours, CvContour.SizeOf, storage, CvConst.CV_POLY_APPROX_DP, 10, true); //ツリーノードイテレータの初期化 writeLog("ツリーノードイテレータを初期化しています..."); CvTreeNodeIterator<CvSeq<CvPoint>> it = new CvTreeNodeIterator<CvSeq<CvPoint>>(contours, 1); foreach (CvSeq<CvPoint> contour in it) { // 輪郭を構成する頂点座標を取得 CvPoint tmp = contour[-1].Value; int vertex_count = contours.Total; writeLog("頂点が" + vertex_count + "個検出されました"); for (int i = 0; i < contour.Total; i++) { int count = i + 1 ; writeLog(count + "回目のトライです"); writeLog("キャリブレーションを試みます..."); if (contour.Total == 4 && contours.Total ==1) { writeLog("4つの頂点と1の矩形が検出されました"); writeLog("射影変換処理を開始します..."); CvPoint point = contour[i].Value; srcImg.Line(tmp, point, CvColor.Blue, 2); Bitmap tmpLine = BitmapConverter.ToBitmap(srcImg); pictureBox4.Image = tmpLine; tmp = point; CvPoint a = contour[0].Value; CvPoint b = contour[1].Value; CvPoint c = contour[2].Value; CvPoint d = contour[3].Value; //src画像用の座標 double[] A = new double[]{ a.X, a.Y, b.X, b.Y, c.X, c.Y, d.X, d.Y }; // 変換先の頂点の座標 double[] B = new double[]{ 0, 0, 0, 720, 960, 720, 960, 0 }; Properties.Settings.Default.X1 = A[0]; Properties.Settings.Default.Y1 = A[1]; Properties.Settings.Default.X2 = A[2]; Properties.Settings.Default.Y2 = A[3]; Properties.Settings.Default.X3 = A[4]; Properties.Settings.Default.Y3 = A[5]; Properties.Settings.Default.X4 = A[6]; Properties.Settings.Default.Y4 = A[7]; Properties.Settings.Default.Save(); homography hom = new homography(); IplImage dst = hom.hom(srcImg, A, B); Bitmap homed = BitmapConverter.ToBitmap(dst); pictureBox5.Image = homed; } else { writeLog("条件を満たさなかったため、射影変換をスキップします"); } timer.Stop(); writeLog("タイマーtimerを停止"); //Bitmap hhh= BitmapConverter.ToBitmap(imgTo); //writeLog("指定色を抽出した画像を右下に表示します"); //pictureBox3.Image = hhh; } } Cv.ReleaseImage(image); writeLog("imageに使用していたメモリを開放します"); } else { writeLog("自動キャリブレーションはスキップされました"); writeLog("マニュアルキャリブレーションを実行します"); Manual ma = new Manual(); writeLog("設定画面を開きます"); DialogResult result = ma.ShowDialog(this); if (!result.Equals(DialogResult.OK)) { // 設定内容を読み込みなおす Properties.Settings.Default.Reload(); writeLog("propertiesをリロードしました"); return; } // 設定内容を保存する Properties.Settings.Default.Save(); writeLog("propertiesを保存しました"); double[] M = new double[]{ Properties.Settings.Default.X1, Properties.Settings.Default.Y1, Properties.Settings.Default.X2, Properties.Settings.Default.Y2, Properties.Settings.Default.X3, Properties.Settings.Default.Y3, Properties.Settings.Default.X4, Properties.Settings.Default.Y4 }; // 変換先の頂点の座標 double[] B = new double[]{ 0, 0, 0, 720, 960, 720, 960, 0 }; homography hom1 = new homography(); IplImage dst = Cv.CreateImage(new CvSize(image.Width, image.Height), BitDepth.U8, 3); dst = hom1.hom(srcImg, M, B); Bitmap homed = BitmapConverter.ToBitmap(dst); pictureBox5.Image = homed; } if (Properties.Settings.Default.MousePaint == true) { ext1 = new Timer(); ext1.Interval = 100; ext1.Tick += new EventHandler(MPloop); ext1.Start(); } else { ext1 = new Timer(); ext1.Interval = 100; ext1.Tick += new EventHandler(homloop); ext1.Start(); } }