用OpenCVSharp 4.5 跑一遍OpenCV官方教程
原OpenCV官方教程链接:OpenCV: Anisotropic image segmentation by a gradient structure tensor
using OpenCvSharp;
using System;
namespace ConsoleApp1
{
class tutorial32 : ITutorial
{
public void Run()
{
//w = 52, C_Thr = 0.43, LowThr = 35, HighThr = 57.
int W = 52; // window size is WxW
double C_Thr = 0.43; // threshold for coherency
int LowThr = 10; // threshold1 for orientation, it ranges from 0 to 180
int HighThr = 80; // threshold2 for orientation, it ranges from 0 to 180
Mat imgIn = Cv2.ImRead("I:\\csharp\\images\\gst_input.jpg", ImreadModes.Grayscale);
if (imgIn.Empty()) //check whether the image is loaded or not
{
Console.Write("ERROR : Image cannot be loaded..!!\n");
return;
}
Mat imgCoherency = new Mat();
Mat imgOrientation = new Mat();
calcGST(imgIn, imgCoherency, out imgOrientation, W);
Mat imgCoherencyBin = imgCoherency.GreaterThan(C_Thr);
// Console.WriteLine(Cv2.Format(imgCoherencyBin));
Mat imgOrientationBin = new Mat();
Cv2.InRange(imgOrientation, new Scalar(LowThr), new Scalar(HighThr), imgOrientationBin);
Mat imgBin = imgCoherencyBin.BitwiseAnd(imgOrientationBin);
Cv2.Normalize(imgCoherency, imgCoherency, 0, 255, NormTypes.MinMax);
Cv2.Normalize(imgOrientation, imgOrientation, 0, 255, NormTypes.MinMax);
Cv2.ImWrite("result.jpg", 0.5 * (imgIn + imgBin));
Cv2.ImWrite("Coherency.jpg", imgCoherency);
Cv2.ImWrite("Orientation.jpg", imgOrientation);
}
private void calcGST(Mat inputImg, Mat imgCoherencyOut, out Mat imgOrientationOut, int w)
{
Mat img = new Mat();
inputImg.ConvertTo(img, MatType.CV_32F);
// GST components calculation (start)
// J = (J11 J12; J12 J22) - GST
Mat imgDiffX = new Mat(), imgDiffY = new Mat(), imgDiffXY = new Mat();
Cv2.Sobel(img, imgDiffX, MatType.CV_32F, 1, 0, 3);
Cv2.Sobel(img, imgDiffY, MatType.CV_32F, 0, 1, 3);
Cv2.Multiply(imgDiffX, imgDiffY, imgDiffXY);
Mat imgDiffXX = new Mat(), imgDiffYY = new Mat();
Cv2.Multiply(imgDiffX, imgDiffX, imgDiffXX);
Cv2.Multiply(imgDiffY, imgDiffY, imgDiffYY);
Mat J11 = new Mat(), J22 = new Mat(), J12 = new Mat(); // J11, J22 and J12 are GST components
Cv2.BoxFilter(imgDiffXX, J11, MatType.CV_32F, new Size(w, w));
Cv2.BoxFilter(imgDiffYY, J22, MatType.CV_32F, new Size(w, w));
Cv2.BoxFilter(imgDiffXY, J12, MatType.CV_32F, new Size(w, w));
// GST components calculation (stop)
// eigenvalue calculation (start)
// lambda1 = 0.5*(J11 + J22 + sqrt((J11-J22)^2 + 4*J12^2))
// lambda2 = 0.5*(J11 + J22 - sqrt((J11-J22)^2 + 4*J12^2))
Mat tmp1, tmp2;
tmp1 = J11 + J22;
tmp2 = J11 - J22;
Mat tmp3 = new Mat(), tmp4 = new Mat();
Cv2.Multiply(tmp2, tmp2, tmp2);
Cv2.Multiply(J12, J12, tmp3);
Cv2.Sqrt(tmp2 + 4.0 * tmp3, tmp4);
Mat lambda1, lambda2;
lambda1 = tmp1 + tmp4;
lambda1 = 0.5 * lambda1; // biggest eigenvalue
lambda2 = tmp1 - tmp4;
lambda2 = 0.5 * lambda2; // smallest eigenvalue
// eigenvalue calculation (stop)
// Coherency calculation (start)
// Coherency = (lambda1 - lambda2)/(lambda1 + lambda2)) - measure of anisotropism
// Coherency is anisotropy degree (consistency of local orientation)
Cv2.Divide(lambda1 - lambda2, lambda1 + lambda2, imgCoherencyOut);
// Coherency calculation (stop)
// orientation angle calculation (start)
// tan(2*Alpha) = 2*J12/(J22 - J11)
// Alpha = 0.5 atan2(2*J12/(J22 - J11))
Mat imgPhase = new Mat();
Cv2.Phase(J22 - J11, 2.0 * J12, imgPhase, true);
imgOrientationOut = 0.5 * imgPhase;
// orientation angle calculation (stop)
}
}
}