using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
namespace NewFeaturesOfOpenCV2._1
{
public partial class FormStereoCorrespondence : Form
{
//私有成员
private string leftImageFileName = "wky_sls_2272x1704.jpg"; //左边的图像文件名
private string rightImageFileName = "wky_sls_2272x1704_2.jpg"; //右边的图像文件名
private Image<Gray, Byte> leftImage = null; //左边的灰度图像
private Image<Gray, Byte> rightImage = null; //右边的灰度图像
private Image<Gray, Int16> disparityImage = null; //差异图像
private Stopwatch sw = new Stopwatch(); //计时器
public FormStereoCorrespondence()
{
InitializeComponent();
}
//设置SGBM的默认参数
private void btnFillDefaultParameters_Click(object sender, EventArgs e)
{
nudSADWindowSize.Value = 3;
nudP1.Value = 0;
nudP2.Value = 0;
nudDisp12MaxDiff.Value = 0;
nudPreFilterCap.Value = 0;
nudUniquenessRatio.Value = 0;
nudSpeckleWindowSize.Value = 0;
nudSpeckleRange.Value = 0;
chkFullDP.Checked = false;
}
//设置SGBM的推荐参数
private void btnFillRecommendedParameters_Click(object sender, EventArgs e)
{
nudUniquenessRatio.Value = 5;
nudSpeckleWindowSize.Value = 50;
nudSpeckleRange.Value = 16;
}
//窗体加载时
private void FormStereoCorrespondence_Load(object sender, EventArgs e)
{
//设置提示
toolTip.SetToolTip(nudNumDisparities, "必须大于0,且能被16除尽");
toolTip.SetToolTip(nudSADWindowSize, "缺省为0;如果指定则必须是正奇数,推荐值为3~11");
toolTip.SetToolTip(nudP1, "缺省为0;推荐值为8*number_of_image_channels*SADWindowSize*SADWindowSize");
toolTip.SetToolTip(nudP2, "缺省为0;如果指定则P2>P1,推荐值为32*number_of_image_channels*SADWindowSize*SADWindowSize");
toolTip.SetToolTip(nudDisp12MaxDiff, "如果设置为负值,则跳过左右差异检查");
toolTip.SetToolTip(nudUniquenessRatio, "缺省为0,推荐值为5~15");
toolTip.SetToolTip(nudSpeckleWindowSize, "缺省为0,推荐值为50~200");
toolTip.SetToolTip(nudSpeckleRange, "缺省为0;如果指定则必须是能被16整除的正数,推荐值为16或者32");
//初始化图像
InitImage(true);
InitImage(false);
}
//加载图像1
private void btnLoadLeftImage_Click(object sender, EventArgs e)
{
LoadImage(true);
}
//加载图像2
private void btnLoadRightImage_Click(object sender, EventArgs e)
{
LoadImage(false);
}
/// <summary>
/// 加载图像
/// </summary>
/// <param name="isLeft">是左边的图像吗?</param>
private void LoadImage(bool isLeft)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.CheckFileExists = true;
ofd.DefaultExt = "jpg";
ofd.Filter = "图片文件|*.jpg;*.png;*.bmp|所有文件|*.*";
if (ofd.ShowDialog(this) == DialogResult.OK)
{
if (ofd.FileName != "")
{
if (isLeft)
leftImageFileName = ofd.FileName;
else
rightImageFileName = ofd.FileName;
InitImage(isLeft);
}
}
ofd.Dispose();
}
/// <summary>
/// 初始化图像
/// </summary>
/// <param name="isLeft">是左边的图像吗?</param>
private void InitImage(bool isLeft)
{
if (isLeft)
{
Image<Bgr, Byte> image = new Image<Bgr, byte>(leftImageFileName);
pbLeft.Image = image.Bitmap;
if (leftImage != null)
leftImage.Dispose();
leftImage = image.Convert<Gray, Byte>();
if (disparityImage != null)
disparityImage.Dispose();
disparityImage = new Image<Gray, short>(leftImage.Size);
image.Dispose();
}
else
{
Image<Bgr, Byte> image = new Image<Bgr, byte>(rightImageFileName);
pbRight.Image = image.Bitmap;
if (rightImage != null)
rightImage.Dispose();
rightImage = image.Convert<Gray, Byte>();
image.Dispose();
}
}
//开始计算
private void btnCalc_Click(object sender, EventArgs e)
{
if (leftImage.Size != rightImage.Size)
{
MessageBox.Show(this, "两幅图像的尺寸不一致,不能比较。", "错误提示");
return;
}
if (tcStereo.SelectedTab == tpStereoSGBM)
{
StereoSGBM sgbm = new StereoSGBM((int)nudMinDisparity.Value, (int)nudNumDisparities.Value, (int)nudSADWindowSize.Value, (int)nudP1.Value,
(int)nudP2.Value, (int)nudDisp12MaxDiff.Value, (int)nudPreFilterCap.Value, (int)nudUniquenessRatio.Value,
(int)nudSpeckleWindowSize.Value, (int)nudSpeckleRange.Value, chkFullDP.Checked);
sw.Stop();
sw.Start();
sgbm.FindStereoCorrespondence(leftImage, rightImage, disparityImage);
sw.Stop();
pbDisparity.Image = disparityImage.Bitmap;
sgbm.Dispose();
lblStatus.Text = string.Format("SGBM比较耗时{0:F04}毫秒。", sw.ElapsedMilliseconds);
}
else if (tcStereo.SelectedTab == tpStereoBM)
{
STEREO_BM_TYPE type = cbBMType.Text == "BASIC" ? STEREO_BM_TYPE.BASIC : (cbBMType.Text == "FISH_EYE" ? STEREO_BM_TYPE.FISH_EYE : STEREO_BM_TYPE.NARROW);
StereoBM bm = new StereoBM(type, (int)nudBMNumberOfDisparities.Value);
sw.Stop();
sw.Start();
bm.FindStereoCorrespondence(leftImage, rightImage, disparityImage);
sw.Stop();
pbDisparity.Image = disparityImage.Bitmap;
bm.Dispose();
lblStatus.Text = string.Format("BM比较耗时{0:F04}毫秒。", sw.ElapsedMilliseconds);
}
else if (tcStereo.SelectedTab == tpStereoGC)
{
StereoGC gc = new StereoGC((int)nudGCNumberOfDisparities.Value, (int)nudGCMaxIters.Value);
Image<Gray, Int16> rightDisparityImage = new Image<Gray, short>(leftImage.Size);
sw.Stop();
sw.Start();
gc.FindStereoCorrespondence(leftImage, rightImage, disparityImage, rightDisparityImage);
sw.Stop();
CvInvoke.cvConvertScale(rightDisparityImage.Ptr, rightDisparityImage.Ptr, 16d, 0d);
CvInvoke.cvConvertScale(disparityImage.Ptr, disparityImage.Ptr, -16d, 0d);
pbDisparity.Image = rightDisparityImage.Bitmap;
rightDisparityImage.Dispose();
gc.Dispose();
lblStatus.Text = string.Format("GC比较耗时{0:F04}毫秒。", sw.ElapsedMilliseconds);
}
}
//关闭窗口时
private void FormStereoCorrespondence_FormClosed(object sender, FormClosedEventArgs e)
{
//释放资源
if (leftImage != null)
leftImage.Dispose();
if (rightImage != null)
rightImage.Dispose();
if (disparityImage != null)
disparityImage.Dispose();
}
}
}