c#读取并转换txt中yolov3数据格式,并在原本图片上进行画框
1.可借鉴的部分:背景线程;StreamReader读取txt文档;yolov3数据格式转换;以及在图片上画框的两种方式。
2.代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System.Drawing.Imaging;
namespace yolov3_bz
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string path;
private void toolStripMenuItem2openFolder_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
path = dialog.SelectedPath;
}
//背景线程
BackgroundWorker bw = new BackgroundWorker();
bw.ProgressChanged += Bw_ProgressChanged;
bw.RunWorkerCompleted += Bw_RunWorkerCompleted;
bw.DoWork += Bw_DoWork;
bw.WorkerReportsProgress = true;
bw.RunWorkerAsync();
}
private void Bw_DoWork(object sender, DoWorkEventArgs e)
{
run();
}
//如果做完了,就在控制台打印“finish”
private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("finish");
}
private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
throw new NotImplementedException();
}
void run()
{
//获取文件夹中所有图片
string[] files = Directory.GetFiles(path);
//遍历
for (int i = 0; i < files.Length; i++)
{
if (files[i].Contains(".txt"))
{
string filename = Path.GetFileNameWithoutExtension(files[i]);
StreamReader streamReader = new StreamReader(files[i]);
string line;
List<List<int>> list = new List<List<int>>();
//读取txt中的数据,可能读到多行
while ((line = streamReader.ReadLine()) != null)
{
string[] str = line.Split(' ');
int w = 1000;
int h = 1000;
double x_ = Convert.ToDouble(str[1]);
double y_ = Convert.ToDouble(str[2]);
double w_ = Convert.ToDouble(str[3]);
double h_ = Convert.ToDouble(str[4]);
//x1,y1框的左上顶点坐标
//x2,y2框的右下顶点坐标
double x1 = w * x_ - 0.5 * w * w_;
double x2 = w * x_ + 0.5 * w * w_;
double y1 = h * y_ - 0.5 * h * h_;
double y2 = h * y_ + 0.5 * h * h_;
//标注框的宽和高
double w1 = Math.Abs(x2 - x1);
double h1 = Math.Abs(y2 - y1);
List<int> a = new List<int>();
a.Add((int)x1);
a.Add((int)y1);
a.Add((int)w1);
a.Add((int)h1);
list.Add(a);
}
//遍历,找取相同文件名的图片,并在图上画框
for (int j = 0; j < files.Length; j++)
{
string name = filename + ".jpg";
if (files[j].Contains(name))
{
//第一种方法
#region
PictureBox pbox = new PictureBox();
pbox.Image = Image.FromFile(files[j]);
using (MemoryStream ms=new MemoryStream())
{
pbox.Image.Save(ms,ImageFormat.Jpeg);
Image img=Image.FromStream(ms);
Graphics g = Graphics.FromImage(img);
for (int z = 0; z < list.Count; z++)
{
g.DrawRectangle(new Pen(Color.Red, 4), new Rectangle(list[z][0], list[z][1], list[z][2], list[z][3]));
}
img.Save("./images/" + filename + ".jpg");
}
break;
#endregion
//第二种方法,用到的是opencvsharp,但是画出来的框是有时候是黑色的,有时候是彩色的,所以不太推荐这种方法
#region
//Bitmap bitmap = new Bitmap(files[j]);
//Mat mat = BitmapConverter.ToMat(bitmap);
// for (int z = 0; z < list.Count; z++)
// {
// Cv2.Rectangle(mat, new Rect(list[z][0], list[z][1], list[z][2], list[z][3]), Scalar.Red, 20, LineTypes.AntiAlias);
// }
将图片保存在文件夹中
// mat.SaveImage("./images/" + filename + ".jpg");
// break;
#endregion
//失败方法,成功方法参考方法一,这种方法就是在白图上画框,原来的图片就看不见了
#region
//Image img = Image.FromFile(files[j]);
//Bitmap bitmap=new Bitmap(img.Width, img.Height,PixelFormat.Format32bppArgb);
//Graphics g = Graphics.FromImage(bitmap);
//for (int z = 0; z < list.Count; z++)
//{
// g.DrawRectangle(new Pen(Color.Red,2),new Rectangle(list[z][0], list[z][1], list[z][2], list[z][3]));
//}
//bitmap.Save("./images/" + filename + ".jpg");
//break;
#endregion
}
}
}
}
}
}
}