发布:2024/2/4 13:56:37作者:管理员 来源:本站 浏览次数:467
用 OpenCVSharp 4.5 跑一遍 OpenCV官方教程
原官方教程链接:OpenCV: Video Input with OpenCV and similarity measurement
using System;
using OpenCvSharp;
namespace ConsoleApp1
{
class tutorial34 : ITutorial
{
public void Run()
{
int psnrTriggerValue = 40, delay = 100;
string sourceReference = @"I:\csharp\videos\Megamind.avi";
string sourceCompareWith = @"I:\csharp\videos\Megamind_bugy.avi";
int frameNum = -1; // Frame counter
VideoCapture captRefrnc = new VideoCapture(sourceReference);
VideoCapture captUndTst = new VideoCapture(sourceCompareWith);
if (!captRefrnc.IsOpened())
{
Console.WriteLine("Could not open reference {0}", sourceReference);
return;
}
if (!captUndTst.IsOpened())
{
Console.WriteLine("Could not open case test {0}", sourceCompareWith);
return;
}
Size refS = new Size((int)captRefrnc.Get(VideoCaptureProperties.FrameWidth),
(int)captRefrnc.Get(VideoCaptureProperties.FrameHeight)),
uTSi = new Size((int)captUndTst.Get(VideoCaptureProperties.FrameWidth),
(int)captUndTst.Get(VideoCaptureProperties.FrameHeight));
if (refS != uTSi)
{
Console.WriteLine("Inputs have different size!!! Closing.");
return;
}
string WIN_UT = "Under Test";
string WIN_RF = "Reference";
// Windows
Cv2.NamedWindow(WIN_RF, WindowFlags.AutoSize);
Cv2.NamedWindow(WIN_UT, WindowFlags.AutoSize);
Cv2.MoveWindow(WIN_RF, 400, 0); //750, 2 (bernat =0)
Cv2.MoveWindow(WIN_UT, refS.Width, 0); //1500, 2
Console.WriteLine("Reference frame resolution: Width={0},Height={1} of nr#", refS.Width, refS.Height, captRefrnc.Get(VideoCaptureProperties.FrameCount));
Console.WriteLine("PSNR trigger value {0}", psnrTriggerValue);
Mat frameReference = new Mat(), frameUnderTest = new Mat();
double psnrV;
Scalar mssimV;
for (; ; ) //Show the image captured in the window and repeat
{
captRefrnc.Read(frameReference);
captUndTst.Read(frameUnderTest);
if (frameReference.Empty() || frameUnderTest.Empty())
{
Console.WriteLine(" < < < Game over! > > > ");
break;
}
++frameNum;
Console.Write("Frame: {0} #", frameNum);
psnrV = getPSNR(frameReference, frameUnderTest);
Console.Write("PSNR {0} dB", psnrV);
if (psnrV < psnrTriggerValue && psnrV > 0)
{
mssimV = getMSSIM(frameReference, frameUnderTest);
Console.Write(" MSSIM: R {0}%, G {1}%, B {2}% ", mssimV.Val2 * 100, mssimV.Val1 * 100, mssimV.Val0 * 100);
}
Console.WriteLine("");
Cv2.ImShow(WIN_RF, frameReference);
Cv2.ImShow(WIN_UT, frameUnderTest);
char c = (char)Cv2.WaitKey(delay);
if (c == 27) break;
}
}
// ![get-psnr]
private double getPSNR(Mat I1, Mat I2)
{
Mat s1 = new Mat();
Cv2.Absdiff(I1, I2, s1); // |I1 - I2|
s1.ConvertTo(s1, MatType.CV_32F); // cannot make a square on 8 bits
s1 = s1.Mul(s1); // |I1 - I2|^2
Scalar s = Cv2.Sum(s1); // sum elements per channel
double sse = s.Val0 + s.Val1 + s.Val2; // sum channels
if (sse <= 1e-10) // for small values return zero
return 0;
else
{
double mse = sse / (double)(I1.Channels() * I1.Total());
double psnr = 10.0 * Math.Log10((255 * 255) / mse);
return psnr;
}
}
// ![get-psnr]
// ![get-mssim]
private Scalar getMSSIM(Mat i1, Mat i2)
{
const double C1 = 6.5025, C2 = 58.5225;
/***************************** INITS **********************************/
//int d = CV_32F;
Mat I1 = new Mat(), I2 = new Mat();
i1.ConvertTo(I1, MatType.CV_32F); // cannot calculate on one byte large values
i2.ConvertTo(I2, MatType.CV_32F);
Mat I2_2 = I2.Mul(I2); // I2^2
Mat I1_2 = I1.Mul(I1); // I1^2
Mat I1_I2 = I1.Mul(I2); // I1 * I2
/*************************** END INITS **********************************/
Mat mu1 = new Mat(), mu2 = new Mat(); // PRELIMINARY COMPUTING
Cv2.GaussianBlur(I1, mu1, new Size(11, 11), 1.5);
Cv2.GaussianBlur(I2, mu2, new Size(11, 11), 1.5);
Mat mu1_2 = mu1.Mul(mu1);
Mat mu2_2 = mu2.Mul(mu2);
Mat mu1_mu2 = mu1.Mul(mu2);
Mat sigma1_2 = new Mat(), sigma2_2 = new Mat(), sigma12 = new Mat();
Cv2.GaussianBlur(I1_2, sigma1_2, new Size(11, 11), 1.5);
sigma1_2 -= mu1_2;
Cv2.GaussianBlur(I2_2, sigma2_2, new Size(11, 11), 1.5);
sigma2_2 -= mu2_2;
Cv2.GaussianBlur(I1_I2, sigma12, new Size(11, 11), 1.5);
sigma12 -= mu1_mu2;
Mat t1, t2, t3;
t1 = 2 * mu1_mu2 + C1;
t2 = 2 * sigma12 + C2;
t3 = t1.Mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
t1 = mu1_2 + mu2_2 + C1;
t2 = sigma1_2 + sigma2_2 + C2;
t1 = t1.Mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
Mat ssim_map = new Mat();
Cv2.Divide(t3, t1, ssim_map); // ssim_map = t3./t1;
Scalar mssim = Cv2.Mean(ssim_map); // mssim = average of ssim map
return mssim;
}
}
}
© Copyright 2014 - 2025 柏港建站平台 ejk5.com. 渝ICP备16000791号-4