本件は、次の質問に続くものです。
C# 上で画像を射影変換したい。その2 (Windows10, Visual Studio 2019, C#, .Net 4.7)
以下の経緯に述べるとおり、「一応、できるようになった」と思われます。
ただし、使用したライブラリは「OpenCvSharp-AnyCPU v2.4.10.2017306」です。
このライブラリを「OpenCvSharp4 v4.3.0.20200421」に変更しようとすると、大量のエラーが出ます。
#経緯
400x300 の大きさの画像があり、この画像の一部(四角形の部分)を引き伸ばして長方形にしようと考えています。具体的には、次の画像のような状態です。
#環境
Windows10, Visual Studio 2019, C#, .Net 4.7 の環境で作成しています。
NuGet として、OpenCvSharp-AnyCPU v2.4.10.2017306 を使用しました。
#ソースコード
次のようにしました。
C#
1using OpenCvSharp; 2using OpenCvSharp.Extensions; 3using System.Drawing; 4using System.Drawing.Drawing2D; 5using System.Windows.Forms; 6 7namespace test20 8{ 9 public partial class Form1 : Form 10 { 11 public Form1() 12 { 13 InitializeComponent(); 14 this.Size = new Size(900, 750); 15 16 Point px1 = new Point(95, 95); 17 Point px2 = new Point(360, 32); 18 Point px3 = new Point(300, 240); 19 Point px4 = new Point(50, 200); 20 21 Image img = global::test20.Properties.Resources._400x300; 22 23 // 元の画像を表示 24 PictureBox p0 = new PictureBox(); 25 p0.Image = img; 26 p0.Location = new Point(30, 30); 27 p0.Size = new Size(400, 300); 28 this.Controls.Add(p0); 29 30 // 元の画像に四角形を表示 31 PictureBox p1 = new PictureBox(); 32 Bitmap bt1 = new Bitmap(400, 300); 33 Graphics gp1 = Graphics.FromImage(bt1); 34 gp1.DrawImage(img, 0,0,400, 300); 35 36 Pen skyBluePen = new Pen(Brushes.DeepSkyBlue); 37 skyBluePen.Width = 4.0F; 38 39 gp1.DrawLine(skyBluePen, px1, px2); 40 gp1.DrawLine(skyBluePen, px2, px3); 41 gp1.DrawLine(skyBluePen, px3, px4); 42 gp1.DrawLine(skyBluePen, px4, px1); 43 44 p1.Image = bt1; 45 p1.Location = new Point(30, 360); 46 p1.Size = new Size(400, 300); 47 this.Controls.Add(p1); 48 49 // 四角形で切り取って表示 50 Point[] p2pt = { px1, px2, px3, px4 }; 51 GraphicsPath p2path = new GraphicsPath(); 52 p2path.AddPolygon(p2pt); 53 Region p2region = new Region(p2path); 54 Bitmap p2btm = new Bitmap(400, 300); 55 Graphics gp2 = Graphics.FromImage(p2btm); 56 gp2.Clip = p2region; 57 gp2.DrawImage(img, gp1.VisibleClipBounds); 58 59 PictureBox p2 = new PictureBox(); 60 p2.Image = p2btm; 61 p2.Location = new System.Drawing.Point(450, 30); 62 p2.Size = new System.Drawing.Size(400, 300); 63 this.Controls.Add(p2); 64 65 66 // p2の四角形を引き伸ばして表示する 67 IplImage src_img = BitmapConverter.ToIplImage((Bitmap)img); 68 IplImage dst_img = Cv.CloneImage(src_img); 69 70 // 四角形の変換前と変換後の対応する頂点をそれぞれセットする 71 CvPoint2D32f[] src_pt = new CvPoint2D32f[4]; 72 src_pt[0] = new CvPoint2D32f(px1.X, px1.Y); 73 src_pt[1] = new CvPoint2D32f(px2.X, px2.Y); 74 src_pt[2] = new CvPoint2D32f(px3.X, px3.Y); 75 src_pt[3] = new CvPoint2D32f(px4.X, px4.Y); 76 77 CvPoint2D32f[] dst_pt = new CvPoint2D32f[4]; 78 dst_pt[0] = new CvPoint2D32f(0, 0); 79 dst_pt[1] = new CvPoint2D32f(399, 0); 80 dst_pt[2] = new CvPoint2D32f(399, 299); 81 dst_pt[3] = new CvPoint2D32f(0, 299); 82 83 CvMat map_matrix = Cv.GetPerspectiveTransform(src_pt, dst_pt); 84 85 // 指定された透視投影変換行列により,cvWarpPerspectiveを用いて画像を変換させる 86 Cv.WarpPerspective(src_img, dst_img, map_matrix, 87 Interpolation.Linear | Interpolation.FillOutliers, Cv.ScalarAll(10)); 88 89 // 結果を表示する 90 PictureBox p3 = new PictureBox(); 91 p3.Image = dst_img.ToBitmap(); 92 p3.Location = new System.Drawing.Point(450, 360); 93 p3.Size = new System.Drawing.Size(400, 300); 94 this.Controls.Add(p3); 95 } 96 } 97}
この時点では、エラーは出ていません。
#エラーコード
さて、上の図にあるとおり、「このパッケージは、従来型で、もう維持されなくなっているめ、非推奨になりました」とありますので、代替バッケージの OpenvSharp4 をインストールしようとしました。
まず、「OpenCvSharp-AnyCPU」をアンイストールしました。このときには、次のようにエラーが表示されました。
次に OpenCvSharp4 をインストールするために検索しました。
#お聞きしたいこと
0. そもそも、インストールすべきパッケージが間違っているのでしょうか。
0. NuGet でインストールした後に、なにか設定すべきことがあるのでしょうか。
0. 「あいまいな参照」とありますので、プレフィックスをつけようとするのですが、うまく認識してくれません。あいまいな参照を回避するには、どうすればよいのでしょうか。
0. その他、正しく実行するためには、どうすればよろしいでしょうか。
お手数ですが、教えていただければ幸いです。
#追記・以下のとおり解決しました。
まず、コメントで教えていただいたとおり、OpenCvSharp4.Windows をインストールしました。
次に、コードを次のように変更しました。
C#
1using OpenCvSharp; 2using OpenCvSharp.Extensions; 3using System.Drawing; 4using System.Drawing.Drawing2D; 5using System.Windows.Forms; 6 7namespace test21 8{ 9 public partial class Form1 : Form 10 { 11 public Form1() 12 { 13 InitializeComponent(); 14 15 this.Size = new System.Drawing.Size(900, 750); 16 17 System.Drawing.Point px1 = new System.Drawing.Point(95, 95); 18 System.Drawing.Point px2 = new System.Drawing.Point(360, 32); 19 System.Drawing.Point px3 = new System.Drawing.Point(300, 240); 20 System.Drawing.Point px4 = new System.Drawing.Point(50, 200); 21 22 Image img = global::test21.Properties.Resources._400x300; 23 24 // 元の画像を表示 25 PictureBox p0 = new PictureBox(); 26 p0.Image = img; 27 p0.Location = new System.Drawing.Point(30, 30); 28 p0.Size = new System.Drawing.Size(400, 300); 29 this.Controls.Add(p0); 30 31 // 元の画像に四角形を表示 32 PictureBox p1 = new PictureBox(); 33 Bitmap bt1 = new Bitmap(400, 300); 34 Graphics gp1 = Graphics.FromImage(bt1); 35 gp1.DrawImage(img, 0, 0, 400, 300); 36 37 Pen skyBluePen = new Pen(Brushes.DeepSkyBlue); 38 skyBluePen.Width = 4.0F; 39 40 gp1.DrawLine(skyBluePen, px1, px2); 41 gp1.DrawLine(skyBluePen, px2, px3); 42 gp1.DrawLine(skyBluePen, px3, px4); 43 gp1.DrawLine(skyBluePen, px4, px1); 44 45 p1.Image = bt1; 46 p1.Location = new System.Drawing.Point(30, 360); 47 p1.Size = new System.Drawing.Size(400, 300); 48 this.Controls.Add(p1); 49 50 // 四角形で切り取って表示 51 System.Drawing.Point[] p2pt = { px1, px2, px3, px4 }; 52 GraphicsPath p2path = new GraphicsPath(); 53 p2path.AddPolygon(p2pt); 54 Region p2region = new Region(p2path); 55 Bitmap p2btm = new Bitmap(400, 300); 56 Graphics gp2 = Graphics.FromImage(p2btm); 57 gp2.Clip = p2region; 58 gp2.DrawImage(img, gp1.VisibleClipBounds); 59 60 PictureBox p2 = new PictureBox(); 61 p2.Image = p2btm; 62 p2.Location = new System.Drawing.Point(450, 30); 63 p2.Size = new System.Drawing.Size(400, 300); 64 this.Controls.Add(p2); 65 66 67 // p2の四角形を引き伸ばして表示する 68 Mat src_img = BitmapConverter.ToMat((Bitmap)img); 69 Mat dst_img = src_img; 70 71 // 四角形の変換前と変換後の対応する頂点をそれぞれセットする 72 Point2f[] src_pt = new Point2f[4]; 73 src_pt[0] = new Point2f(px1.X, px1.Y); 74 src_pt[1] = new Point2f(px2.X, px2.Y); 75 src_pt[2] = new Point2f(px3.X, px3.Y); 76 src_pt[3] = new Point2f(px4.X, px4.Y); 77 78 Point2f[] dst_pt = new Point2f[4]; 79 dst_pt[0] = new Point2f(0, 0); 80 dst_pt[1] = new Point2f(399, 0); 81 dst_pt[2] = new Point2f(399, 299); 82 dst_pt[3] = new Point2f(0, 299); 83 84 Mat map_matrix = Cv2.GetPerspectiveTransform(src_pt, dst_pt); 85 86 // 指定された透視投影変換行列により,cvWarpPerspectiveを用いて画像を変換させる 87 OpenCvSharp.Size mysize = new OpenCvSharp.Size(400, 300); 88 InterpolationFlags OIFLiner = InterpolationFlags.Linear; 89 BorderTypes OBTDefault = BorderTypes.Default; 90 Cv2.WarpPerspective(src_img, dst_img, map_matrix, mysize, OIFLiner, OBTDefault); 91 92 // 結果を表示する 93 PictureBox p3 = new PictureBox(); 94 p3.Image = dst_img.ToBitmap(); 95 p3.Location = new System.Drawing.Point(450, 360); 96 p3.Size = new System.Drawing.Size(400, 300); 97 this.Controls.Add(p3); 98 } 99 } 100}
ありがとうございました。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/25 11:15 編集