using System; using System.Numerics; using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.Util; namespace ImageMinipulation { /// /// All programs are made using videos from (Programming with Chris) video seiress /// public class vanGoghFilters { /// /// Displays an image in a window and displays the same image but bluerd in a new window /// public void One() { Mat pic = new Mat(); Mat gaussianBlur = new Mat(); pic = CvInvoke.Imread("./img/StarryNight.jpg"); CvInvoke.GaussianBlur(pic, gaussianBlur, new System.Drawing.Size(15, 15), 5.0); CvInvoke.Imshow("starry night", pic); CvInvoke.Imshow("blurry night", gaussianBlur); CvInvoke.WaitKey(); } /// /// Resizes and image to a predetermined amount /// public void Two() { Mat pic = CvInvoke.Imread("./img/StarryNight.jpg"); Mat resizedPic = new Mat(); int height = pic.Rows; int width = pic.Cols; Console.WriteLine($"Starry Night is : {width} x {height}"); CvInvoke.Resize(pic, resizedPic, new System.Drawing.Size(400, 500)); CvInvoke.Imshow("Starry Night", pic); CvInvoke.Imshow("resized Night", resizedPic); CvInvoke.WaitKey(); } /// /// Rotates an image around the center 45 degrees /// public void Three() { Mat pic = CvInvoke.Imread("./img/StarryNight.jpg"); Mat rotatedPic = new Mat(); double angleFortyFive = 45; int width = pic.Cols; int height = pic.Rows; System.Drawing.PointF center = new System.Drawing.PointF((width - 1) / 2.0f, (height - 1) / 2.0f); Mat rotationMatrix = new Mat(); CvInvoke.GetRotationMatrix2D(center, angleFortyFive, 1.0, rotationMatrix); CvInvoke.WarpAffine(pic, rotatedPic, rotationMatrix, new System.Drawing.Size(width, height)); CvInvoke.Imshow("Rotated Night", rotatedPic); CvInvoke.WaitKey(); } /// /// Changing the color of pixels inside a range to new colors /// public void Four() { Mat pic = CvInvoke.Imread("./img/StarryNight.jpg"); Image convertPic = pic.ToImage(); int width = pic.Cols; int height = pic.Rows; var image = convertPic.InRange(new Bgr(75, 0, 0), new Bgr(255, 125, 125)); for (int i = 0; i < image.Rows; i++) { for (int j = 0; j < image.Cols; j++) { var num = image[i, j]; if (num.Intensity > 0) { convertPic[i, j] = new Bgr(convertPic[i, j].MCvScalar.V0 - 50, convertPic[i, j].MCvScalar.V1 + 100, convertPic[i, j].MCvScalar.V2 - 50); } } } Mat changedPic = convertPic.Mat; CvInvoke.Imshow("Starry Night", pic); CvInvoke.Imshow("Color-Shifted Night", changedPic); CvInvoke.WaitKey(); } /// /// Adds a sharpen filter to a picture based on an array /// public void Five() { Mat pic = CvInvoke.Imread("./img/StarryNight.jpg"); /// This is a 3D matrix, and we will be using a process called convoluion /// Convolution is the application of a kernel to each individual pixal and it's surrounding pixels /// then you take that value and put it back in the pixel and some effect happens depending on the valuse /// in the kernel /// A new convoluted kernal can be looked up for the effect you want (this kernal is basic sharpen) float[,] kernalArray = new float[3, 3] { { 0, -1, 0}, { -1, 5, -1}, { 0, -1, 0} }; ConvolutionKernelF kernal = new ConvolutionKernelF(kernalArray); Mat filteredPic = new Mat(); pic.CopyTo(filteredPic); CvInvoke.Filter2D(pic, filteredPic, kernal, new System.Drawing.Point(0, 0)); CvInvoke.Imshow("Convoluted Night", filteredPic); CvInvoke.WaitKey(); } /// /// Uses the sobel edge detection to output just the edges in the image /// public void Six() { Mat pic = CvInvoke.Imread("./img/iPhone.jpg"); Mat guassianBlur = new Mat(); Mat sobelX = new Mat(); Mat sobelY = new Mat(); Mat sobelXY = new Mat(); pic.CopyTo(sobelX); pic.CopyTo(sobelY); pic.CopyTo(sobelXY); CvInvoke.GaussianBlur(pic, guassianBlur, new System.Drawing.Size(3, 3), 5.0); CvInvoke.Sobel(guassianBlur, sobelX, Emgu.CV.CvEnum.DepthType.Default, 1, 0, 5); CvInvoke.Sobel(guassianBlur, sobelY, Emgu.CV.CvEnum.DepthType.Default, 0, 1, 5); CvInvoke.Sobel(guassianBlur, sobelXY, Emgu.CV.CvEnum.DepthType.Default, 1, 1, 5); CvInvoke.Imshow("sobelX", sobelX); CvInvoke.Imshow("sobelY", sobelY); CvInvoke.Imshow("sobelXY", sobelXY); CvInvoke.WaitKey(); } /// /// Uses the canny edge detection to output the edges in an image (this method can be a little sharper depending on the image) /// public void Seven() { Mat pic = CvInvoke.Imread("./img/iPhone.jpg"); Mat guassianBlur = new Mat(); Mat cannyPic = new Mat(); var averge = pic.ToImage().GetAverage(); var lowerthreshold = Math.Max(0, (1.0 - 0.33) * averge.Intensity); var upperthreshold = Math.Max(255, (1.0 + 0.33) * averge.Intensity); CvInvoke.GaussianBlur(pic, guassianBlur, new System.Drawing.Size(3, 3), 5.0); CvInvoke.Canny(guassianBlur, cannyPic, lowerthreshold, upperthreshold, 3); CvInvoke.Imshow("Canny", cannyPic); CvInvoke.WaitKey(); } /// /// Makes a threshold image to tell us where the contours are then defines those contours with green lines and fills the contourd parts in with blue /// public void Eight() { Mat pic = CvInvoke.Imread("./img/iPhone.jpg"); Mat thresholdPic = new Mat(); Mat hierarchy = new Mat(); VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); Image grayPic = pic.ToImage(); CvInvoke.Threshold(grayPic, thresholdPic, 210, 255, Emgu.CV.CvEnum.ThresholdType.Binary); CvInvoke.FindContours(thresholdPic, contours, hierarchy, Emgu.CV.CvEnum.RetrType.Tree, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxNone); CvInvoke.DrawContours(pic, contours, -1, new MCvScalar(0, 255, 0), 2); CvInvoke.FillPoly(pic, contours, new MCvScalar(255, 0, 0)); CvInvoke.Imshow("Threshold", thresholdPic); CvInvoke.Imshow("pic with contours", pic); CvInvoke.WaitKey(); } /// /// Template matching, it lookes at a template image then compares that to an overall image and checks if there is anything /// that matches our template then outputs where it found a match /// public void Nine() { Mat answeredPic = CvInvoke.Imread("./img/GraderPage-Answered.jpg"); Mat aWasAnswered = CvInvoke.Imread("./img/A_abcd.jpg"); Mat templateOuput = new Mat(); CvInvoke.Resize(answeredPic, answeredPic, new System.Drawing.Size(0, 0), 0.7d, 0.7d); CvInvoke.Resize(aWasAnswered, aWasAnswered, new System.Drawing.Size(0, 0), 0.7d, 0.7d); CvInvoke.MatchTemplate(answeredPic, aWasAnswered, templateOuput, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed); double minVal = 0.0d; double maxVal = 0.0d; System.Drawing.Point minLoc = new System.Drawing.Point(); System.Drawing.Point maxLoc = new System.Drawing.Point(); CvInvoke.MinMaxLoc(templateOuput, ref minVal, ref maxVal, ref minLoc, ref maxLoc); CvInvoke.Threshold(templateOuput, templateOuput, 0.85, 1, Emgu.CV.CvEnum.ThresholdType.ToZero); var matches = templateOuput.ToImage(); for (int i = 0; i < matches.Rows; i++) { for (int j = 0; j < matches.Cols; j++) { if (matches[i, j].Intensity > .8) { System.Drawing.Point loc = new System.Drawing.Point(j, i); System.Drawing.Rectangle box = new System.Drawing.Rectangle(loc, aWasAnswered.Size); CvInvoke.Rectangle(answeredPic, box, new MCvScalar(0, 255, 0), 2); } } } CvInvoke.Imshow("template detected", answeredPic); CvInvoke.WaitKey(); } } }