コード例 #1
0
ファイル: TestForm.cs プロジェクト: kalomj/KaloVision
        private void VisualizeDenseFlow_Means(ref double vmag, ref double vang)
        {
            Image <Gray, float> flowX = new Image <Gray, float>(currentGray.Size);
            Image <Gray, float> flowY = new Image <Gray, float>(currentGray.Size);
            Image <Gray, float> mag   = new Image <Gray, float>(currentGray.Size);
            Image <Gray, float> ang   = new Image <Gray, float>(currentGray.Size);

            Image <Gray, byte> fullGray = new Image <Gray, byte>(currentImage.Size);

            fullGray.SetValue(new Gray(255));

            if (framesProcessed >= 2)
            {
                CvInvoke.CalcOpticalFlowFarneback(lastGray, currentGray, flowX, flowY, 0.5, 3, 50, 3, 5, 1.2, OpticalflowFarnebackFlag.Default);
                CvInvoke.CartToPolar(flowX, flowY, mag, ang, true);

                CvInvoke.Threshold(mag, mag, 4, float.MaxValue, ThresholdType.ToZero);

                MCvScalar meanang = CvInvoke.Mean(ang.Mat, mag.Convert <Gray, byte>());
                MCvScalar meanmag = CvInvoke.Mean(mag.Mat, mag.Convert <Gray, byte>());

                vmag = meanmag.V0;
                vang = meanang.V0;

                if (vmag > 4)
                {
                    if (minang > vang)
                    {
                        minang = vang;
                    }

                    if (maxang < vang)
                    {
                        maxang = vang;
                    }
                }

                CvInvoke.Normalize(mag, mag, 0, 255, NormType.MinMax);
                CvInvoke.Normalize(ang, ang, 0, 255, NormType.MinMax);

                Image <Hsv, byte> hsv = new Image <Hsv, byte>(new Image <Gray, byte>[] { ang.Convert <Gray, byte>(), fullGray, mag.Convert <Gray, byte>() });

                double x = Math.Cos(vang * (Math.PI / 180.0));
                double y = Math.Sin(vang * (Math.PI / 180.0));

                CvInvoke.CvtColor(hsv, currentImage, ColorConversion.Hsv2Bgr);

                currentImage.Erode(5);
                currentImage.Dilate(5);

                currentImage.Draw(new LineSegment2D(new Point(currentImage.Size.Width / 2, currentImage.Height / 2), new Point((int)(x * 100) + currentImage.Size.Width / 2, (int)(y * 100) + currentImage.Height / 2)), new Bgr(Color.Red), 2);
            }
        }
コード例 #2
0
        public void ProcessSrcToEnd(UMat inImg)
        {
            ///Displays the input image, forward fourier transform(fFt) it and display magnitude of that fFt. It then calls the next function.
            ///Previous name was ProcessSrcTofFt.

            VectorOfUMat ft;                            //forward (Fourier) transform

            using (UMat grayImg = GetBgr2Gray(inImg)) { //make grayScale. It is a copy so as to not mess up the displaying.
                ft = ForwardFt(grayImg);
            }
            // get magnitude and phase from real and imaginary parts
            if (magT != null)
            {
                magT.Dispose();
            }
            magT = new UMat();
            if (phT != null)
            {
                phT.Dispose();
            }
            phT = new UMat();
            CvInvoke.CartToPolar(ft[0], ft[1], this.magT, this.phT);
            ft[0].Dispose();
            ft[1].Dispose();
            ft.Dispose();            //TODO: check whether you have to dispose each UMat individually then the vector. Same for inverse fourier transform's output down there.

            //display magnitude of forward fourier transform
            fTView.Display_Image(GetNorm4Disp(this.magT, log: true));


            if (firstTimeLoadingImage)
            {
                this.firstTimeLoadingImage = false;
                // set rectangle selection to full image (I want user to see all boxes displaying image when start up)
                this.ftSelectedRect = new Rectangle(new Point(0, 0), magT.Size);
                this.oldImgSize     = this.magT.Size;
            }
            else
            {
                //if the new image is smaller than the previous one,
                if (magT.Size.Width < oldImgSize.Width || magT.Size.Height < oldImgSize.Height)                  //TODO: make this smaller-than-image checking a function cause it happens again at the end of processing, or somehow join the 2 to neaten it up.
                //limit the selected rectangle area to within the new image to avoid trying to read outside the image.
                {
                    LimitRectToWithinImage(this.magT, ref this.ftSelectedRect);
                }
            }



            //continue the chain
            ProcessSelRectToEnd(this.ftSelectedRect, this.magT, this.phT);
        }
コード例 #3
0
        private void moduleKeyFrameExtraction(Mat inputMat)
        {
            Image <Bgr, Byte> imageMedianBlur = modulePreProcessing(inputMat);
            //MedianBlur for Feature Extraction

            /*Image<Bgr, Byte> imageFE = new Image<Bgr, Byte>(inputMat.Width, inputMat.Height);
             * CvInvoke.MedianBlur(imageInput, imageFE, 7);
             * pictureBox2.Image = imageFE.Bitmap;*/

            //Sobel
            Image <Gray, float> imageSobelInput = imageMedianBlur.Convert <Gray, float>();
            Image <Gray, float> _imgSobelx      = new Image <Gray, float>(imageSobelInput.Width, imageSobelInput.Height);
            Image <Gray, float> _imgSobely      = new Image <Gray, float>(imageSobelInput.Width, imageSobelInput.Height);

            _imgSobelx = imageSobelInput.Sobel(1, 0, 3);
            _imgSobely = imageSobelInput.Sobel(0, 1, 3);
            Image <Gray, float> magnitude = new Image <Gray, float>(imageSobelInput.Width, imageSobelInput.Height);
            Image <Gray, float> angle     = new Image <Gray, float>(imageSobelInput.Width, imageSobelInput.Height);

            CvInvoke.CartToPolar(_imgSobelx, _imgSobely, magnitude, angle, true);
            //Image box2 image of gradient
            //imageBox3.Image = magnitude;
            //FrameNumber Display
            //label2.Text = frameNumber.ToString();
            double avg = magnitude.GetAverage().Intensity;

            //Chart of gradient
            //chart1.Series["Gradient"].Points.AddXY(frameNumber, avg);
            if (!isFirst)
            {
                if (avg > 0)
                {
                    isFirst = true;
                    first   = frameNumber;
                    isLast  = false;
                }
            }
            if (!isLast)
            {
                if (avg == 0)
                {
                    isLast = true;
                    last   = frameNumber;
                    //label3.Text = "First: " + first + " Last: " + last;
                    int mid = (first + last) / 2;
                    moduleFeatureExtraction(first, last);
                    isFirst = false;
                }
            }
            frameNumber++;
        }
コード例 #4
0
        private static double CountDistanceThroughEdges(Mat leftEdges, Mat rightEdges, Rectangle roi,
                                                        double baseLine, double focalLengthPx)
        {
            if (roi == null)
            {
                return(-1);
            }
            Mat prev8bit    = leftEdges;
            Mat current8bit = rightEdges;

            Image <Gray, byte>  imageLeft  = prev8bit.ToImage <Gray, byte>();
            Image <Gray, byte>  imageRight = current8bit.ToImage <Gray, byte>();
            Image <Gray, float> flowX      = new Image <Gray, float>(prev8bit.Width, prev8bit.Height);
            Image <Gray, float> flowY      = new Image <Gray, float>(prev8bit.Width, prev8bit.Height);

            CvInvoke.CalcOpticalFlowFarneback(imageLeft, imageRight, flowX,
                                              flowY, 0.5, 3, 25, 10, 5, 1.1, OpticalflowFarnebackFlag.FarnebackGaussian);
            Mat magnitude = new Mat();
            Mat angle     = new Mat();

            CvInvoke.CartToPolar(flowX.Mat, flowY.Mat, magnitude, angle);
            int matWidth  = magnitude.Width;
            int matHeight = magnitude.Height;

            float[] magData = new float[matWidth * matHeight];
            magnitude.CopyTo(magData);
            List <double> results = new List <double>();

            for (int x = roi.X; x <= roi.X + roi.Width; x++)
            {
                for (int y = roi.Y; y <= roi.Y + roi.Height; y++)
                {
                    float delta = GetElementFromArrayAsFromMatrix(magData, y, x, matWidth);
                    if (delta < epsilon)
                    {
                        continue;
                    }
                    double distance = (baseLine * focalLengthPx) / delta;
                    results.Add(distance);
                }
            }
            if (results.Count == 0)
            {
                return(-1);
            }

            return(results.Average());
        }
コード例 #5
0
        public static Mat GetEdges(Mat src)
        {
            const Single scharrKernelNormalizationDivisor = 16.0f;
            const Single scharrKernelNormalizationFactor  = 1.0f / scharrKernelNormalizationDivisor;

            src.ConvertTo(src, DepthType.Cv32F, 1 / 255d);

            var gradX = new Mat();
            var gradY = new Mat();

            CvInvoke.Scharr(src, gradX, DepthType.Cv32F, 1, 0, scharrKernelNormalizationFactor);
            CvInvoke.Scharr(src, gradY, DepthType.Cv32F, 0, 1, scharrKernelNormalizationFactor);

            var outImg = new Mat();

            CvInvoke.CartToPolar(gradX, gradY, outImg, new Mat());

            outImg.ConvertTo(outImg, DepthType.Cv8U, 255);

            return(outImg);
        }
コード例 #6
0
        public void InverseT(UMat reIn, UMat imIn, UMat magOut, UMat phOut)
        {
            ///accepts real and imaginary parts, inverse (fourier) Transforms
            ///converts real and imaginary output parts to magnitude and
            ///phase, returns magnitude and phase parts.
            ///Refer to ForwardT() for more info on why I code like this.
            ///Reference: https://stackoverflow.com/questions/16812950/how-do-i-compute-dft-and-its-reverse-with-emgu

            VectorOfUMat vec = this.vec;

            vec.Push(reIn);
            vec.Push(imIn);
            UMat cImg = this.img32f2c;

            CvInvoke.Merge(vec, cImg);            //because Dft method accepts and outputs 2-channel image
            CvInvoke.Dft(cImg, cImg, DxtType.Inverse, 0);
            //new objects put into vec, vec[0] is reOut, vec[1] is imOut.
            CvInvoke.Split(cImg, vec);
            //convert output of inverse Transform to magnitude and polar
            CvInvoke.CartToPolar(vec[0], vec[1], magOut, phOut);
            vec.Clear();
        }
コード例 #7
0
        public void ProcessForwardT(UMat inImg, UMat outMagT, UMat outPhT, bool zeroPad = false, bool switchQuadrants = true)
        {
            ///Accepts a 1-channel image, updates outMagT and outPhT.
            ///magnitude and phase, cause I can't think of why you
            ///would wanna look at real and imaginary Transforms.
            ///Also can't think of how you can get complex-valued images.
            ///Quadrant rearranging doesn't support odd rows or cols.
            ///T stuff, reference: https://docs.opencv.org/master/d8/d01/tutorial_discrete_fourier_transform.html
            //convert image to 32bit float because spacial frequency
            //domain values are way bigger than spatial domain values.
            UMat re = outMagT;            //32-bit float real image, use memory from

            //outMagT cause it's gonna be updated anyway
            inImg.ConvertTo(re, DepthType.Cv32F);
            if (zeroPad)
            {
                //zero pad for faster dft
                ZeroPadImage(re);
            }
            //create imaginary image of zeros of same depthType
            //and size as image representing real plane
            UMat im = outPhT;                                           //imaginary

            im.Create(re.Rows, re.Cols, re.Depth, re.NumberOfChannels); //allocate memory so you can set it to zero array
            //if memory hasn't already been allocated for it
            im.SetTo(new MCvScalar(0));

            /// Quick exerpt about VectorOfUMat:
            /// if you create a VectorOfUMat vec, only if the first UMat variable
            /// to store the object is the vector node, like
            /// VectorOfUMat vec = new VectorOfUmat(new Umat(), new Umat());
            /// vec.Push(someUMat.Clone());
            /// then vec.Dispose/Clear actually disposes all the objects referenced
            /// to by the UMats in vec. In this case, if you did:
            /// VectorOfUMat vec = new VectorOfUMat(inImg.Clone(), inImg.Clone());
            /// UMat one = vec[0];
            /// one.Dispose();
            /// one.Dispose actually does nothing.
            /// Otherwise, if
            /// UMat one = new UMat();
            /// UMat two = new UMat();
            /// VectorOfUMat vec = new VectorOfUmat(one);
            /// vec.Push(two);
            /// calling vec.Dispose() doesn't dispose the objects.
            /// you have to call one.Dispose and two.Dispose.
            /// Note: no matter whether the UMat's first variable stored
            /// in is in a vector node or not, calling vec[index].Dispose
            /// does NOTHING.
            /// The situation is the same for vec.Clear, except Clear doesn't
            /// dispose of vec itself, it just disposes the objects the UMats in
            /// it reference to.
            //Dft accepts 2-channel images, so we use Merge to merge
            //our 2 1-channel images into a single 2-channel image.
            //Merge accepts object arrays, so we create a VectorOfUMat
            //of our 2 images to feed into Merge.

            VectorOfUMat vec  = this.vec;
            UMat         cImg = this.img32f2c;

            vec.Push(re);
            vec.Push(im);            //vec[0] = re, vec[1] = im
            ;
            CvInvoke.Merge(vec, cImg);
            CvInvoke.Dft(cImg, cImg, DxtType.Forward, 0);            //use back the same memory
            //switch quadrants while images are still combined
            if (switchQuadrants)
            {
                SwitchQuadrants(cImg);
            }
            //make the 2-channel array into 2 1-channel arrays
            CvInvoke.Split(cImg, vec); //vec[0] is reT, vec[1] is imT, they are new objects.
            CvInvoke.CartToPolar(vec[0], vec[1], outMagT, outPhT);
            vec.Clear();               //dispose reT and imT.TODO: find a way to get rid of allocating memory for reT and imT.
        }
コード例 #8
0
        public void ProcessAddPhaseToEnd(
            double rDist,
            double sensorPixelWidth,
            double sensorPixelHeight,
            double wavelength,
            UMat magFoT,
            UMat phFoT,
            Rectangle ctrRect,
            Point selRectMaxMagPoint)
        {
            ///Based on a bunch of parameters (as you can see in the input), calculates the phase difference for each plane wave
            ///between the aperture(hologram) plane and image plane. It adds this phase difference to each plane wave, turning the
            ///fourier spectrum into one at the image plane, and then inverse fourier transforms to get the predicted magnitude and
            ///phase of light at the image plane. It then displays the predicted magnitude and phase images.
            ///This version modifies the original phF)). For Video mode.
            ///
            /// This next part is just me rambling over the minimal parameters to choose and the ups and downs of each set.
            ///I went for just passing already calculated values instead of recalculating them.
            ///1. create matrix of size ( phCtrFoT OR ctrRect, which contains location info )
            ///2. value at each point is based on distance from ( rectSelMaxMagLocations[0] OR from ctrRect:
            ///Point FoT0HzPoint = new Point(magFoT.Cols / 2, magFoT.Rows / 2);
            ///Point rectSelMaxMagLocation = ctrRect.Location.Minus(FOT0HzPoint);
            ///3. copy over to phCtrFoT, which if you choose ctrRect and null, you have to create another header.
            ///
            ///I choose (phCtrFoT, roiMaxMagLoc)!
            ///
            ///However, due to needing to clone phFoT, and hence phCtrFoT as well to preserve the original when in static
            ///image mode, I chose (ctrRect, selRectMaxMagLocation) instead.


            //Calculate phase difference matrix to add to sinewaves at particular (x,y)s.
            //As much calculation is taken out of the loop as possible.
            //done with image class because it is faster than Matrix<type> class.
            //Only difference between image class and umat/mat (for this function) is at CvInvoke.Add,
            //where umat/mat takes 100ms less time in 17s. Not worth the extra carefulness (yet).
            double sensorHeight          = phFoT.Rows * sensorPixelHeight;
            double sensorWidth           = phFoT.Cols * sensorPixelWidth;
            double xFreqInterval         = 1 / sensorWidth;
            double yFreqInterval         = 1 / sensorHeight;
            double xFreqITimesWavelength = xFreqInterval * wavelength;
            double yFreqITimesWavelength = yFreqInterval * wavelength;
            double wavenumber            = 2 * Math.PI / wavelength;

            Image <Gray, float> phDiffMat = new Image <Gray, float>(ctrRect.Size);
            int rows = phDiffMat.Rows;
            int cols = phDiffMat.Cols;

            for (int y = 0; y < rows; ++y)
            {
                for (int x = 0; x < cols; ++x)
                {
                    double xTFreq                = x - selRectMaxMagPoint.X;     //fourier transform frequency
                    double yTFreq                = y - selRectMaxMagPoint.Y;
                    double gammaX                = xTFreq * xFreqITimesWavelength;
                    double gammaY                = yTFreq * yFreqITimesWavelength;
                    double gammaXSqred           = gammaX * gammaX;
                    double gammaYSqred           = gammaY * gammaY;
                    double insideSqrt            = 1 - gammaXSqred - gammaYSqred;
                    double sqrted                = Math.Sqrt(insideSqrt);
                    double sqrtedTimesWavenumber = sqrted * wavenumber;
                    double ph  = rDist * sqrtedTimesWavenumber;
                    float  fPh = (float)ph;
                    phDiffMat.Data[y, x, 0] = fPh;
                }
            }

            //if video mode is off, add phase difference to a copy of the first-order-only image,
            //because we don't want to modify the input
            UMat phFoT2Process, phCtrFoT2Process;                    //variable 2

            if (video == false)                                      //create a copy to preserve the original
            {
                phFoT2Process    = phFoT.Clone();                    //a copy
                phCtrFoT2Process = new UMat(phFoT2Process, ctrRect); //roi of the copy
            }
            else
            {
                phFoT2Process    = phFoT;                    //not-a-copy
                phCtrFoT2Process = new UMat(phFoT, ctrRect); //roi of not-a-copy
            }
            CvInvoke.Add(phCtrFoT2Process, phDiffMat, phCtrFoT2Process, dtype: DepthType.Cv32F);
            phDiffMat.Dispose();



            VectorOfUMat iFt;

            //convert magnitude and phase to real and imaginary images to input into inverse fourier transform function
            using (UMat reFoT = new UMat(), imFoT = new UMat()) {
                CvInvoke.PolarToCart(magFoT, phFoT2Process, reFoT, imFoT);
                if (video == false)
                {
                    //disposing phFoT2Process also takes care of phCtrFoT2Process, as the latter is an ROI of the first.
                    phFoT2Process.Dispose();
                }
                iFt = InverseFt(reFoT, imFoT);                 // inverse fourier transform
            }

            // get magnitude and phase from real and imaginary parts
            UMat magFo = new UMat();
            UMat phFo  = new UMat();

            CvInvoke.CartToPolar(iFt[0], iFt[1], magFo, phFo);
            iFt.Dispose();             //disposes the real and imaginary images inside it too.

            intensityView.Display_Image(GetNorm4Disp(magFo, log: true));

            phaseView.Display_Image(GetNorm4Disp(phFo));

            //if the new image is different size from the previous one,
            if (magT.Size.Width < oldImgSize.Width || magT.Size.Height < oldImgSize.Height)
            {
                //Make the images fit their imageBoxes so the user sees the whole image loaded at first.
                //FitImageToImageBox(imageBox1);
                //FitImageToImageBox(imageBox2);
                //FitImageToImageBox(imageBox3);
                //FitImageToImageBox(imageBox4);
            }
            this.oldImgSize = this.magFoT.Size;
        }
コード例 #9
0
ファイル: TestForm.cs プロジェクト: kalomj/KaloVision
        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            if (
                false &&
                framesProcessed == 2)
            {
                updateTimer.Stop();
                return;
            }

            double rho       = 0.0;
            double theta_deg = 0.0;

            perfSw.Restart();

            try
            {
                framesProcessed++;

                //store last gray image, pull current image, convert to gray
                lastGray     = currentGray;
                currentImage = capture.QueryFrame().ToImage <Bgr, Byte>();

                Image <Gray, byte> grayImage = new Image <Gray, byte>(currentImage.Size);
                CvInvoke.CvtColor(currentImage, grayImage, ColorConversion.Bgr2Gray);

                //apply gaussian blur to gray to smooth out noise
                CvInvoke.GaussianBlur(grayImage, grayImage, new Size(15, 15), 1.8);

                currentGray = grayImage;

                //create variables to store optical flow in cart and polar coordinates
                Image <Gray, float> flowX = new Image <Gray, float>(currentGray.Size);
                Image <Gray, float> flowY = new Image <Gray, float>(currentGray.Size);
                Image <Gray, float> mag   = new Image <Gray, float>(currentGray.Size);
                Image <Gray, float> ang   = new Image <Gray, float>(currentGray.Size);

                //image with all values set to 255
                Image <Gray, byte> fullGray = new Image <Gray, byte>(currentImage.Size);
                fullGray.SetValue(new Gray(255));


                //wait until second frame to get flow
                if (framesProcessed >= 2)
                {
                    int threshold = 2;

                    //get flow images
                    CvInvoke.CalcOpticalFlowFarneback(lastGray, currentGray, flowX, flowY, 0.5, 3, 20, 3, 5, 1.2, OpticalflowFarnebackFlag.Default);

                    //convert x and y flow to magnitude and angle images
                    CvInvoke.CartToPolar(flowX, flowY, mag, ang, true);

                    //threshold the magnitude so we only look at vectors with motion
                    CvInvoke.Threshold(mag, mag, threshold, 1.0, ThresholdType.Binary);

                    //find the total number of pixels in the image that are over the threshold value
                    MCvScalar sumMask = CvInvoke.Sum(mag);

                    //apply the mask to the flow vectors
                    flowX = flowX.Copy(mag.Convert <Gray, byte>());
                    flowY = flowY.Copy(mag.Convert <Gray, byte>());

                    //sum of flow vector components
                    MCvScalar sumX = CvInvoke.Sum(flowX);
                    MCvScalar sumY = CvInvoke.Sum(flowY);

                    double avgX = 0.0;
                    double avgY = 0.0;

                    //avg of flow vector components
                    if (sumMask.V0 > 0.0)
                    {
                        avgX = sumX.V0 / sumMask.V0;
                        avgY = sumY.V0 / sumMask.V0;
                    }

                    //convert to polar radius (rho) and angle (theta)
                    rho = Math.Sqrt(avgX * avgX + avgY * avgY);
                    double theta = Math.Atan2(avgY, avgX);

                    //convert angle from radians to degrees
                    theta_deg = theta * 180 / Math.PI;

                    //clamp values to bytes for HSV image visualization
                    CvInvoke.Normalize(mag, mag, 0, 255, NormType.MinMax);
                    CvInvoke.Normalize(ang, ang, 0, 255, NormType.MinMax);

                    //create hue/saturation/value image to visualize magnitude and angle of flow
                    Image <Hsv, byte> hsv = new Image <Hsv, byte>(new Image <Gray, byte>[] { ang.Convert <Gray, byte>(), fullGray, mag.Convert <Gray, byte>() });

                    //adding average flow components history
                    avgXHistory.Add(avgX);
                    avgYHistory.Add(avgY);

                    double rho_avg = 0.0;
                    double x_avg   = 0.0;
                    double y_avg   = 0.0;

                    int smoothLength = 3;

                    //get average angle in the history
                    if (avgXHistory.Count() > 0)
                    {
                        x_avg   = avgXHistory.Median(smoothLength);
                        y_avg   = avgYHistory.Median(smoothLength);
                        rho_avg = Math.Sqrt(x_avg * x_avg + y_avg * y_avg);
                    }

                    //convert hsv to bgr image for bitmap conversion
                    CvInvoke.CvtColor(hsv, currentImage, ColorConversion.Hsv2Bgr);

                    //draw instaneous average flow direction line if magnitude exceeds threshold
                    if (rho > threshold)
                    {
                        currentImage.Draw(new LineSegment2D(new Point(currentImage.Size.Width / 2, currentImage.Height / 2), new Point((int)(avgX * 10) + currentImage.Size.Width / 2, (int)(avgY * 10) + currentImage.Height / 2)), new Bgr(Color.Red), 2);
                    }

                    //draw historical average flow direction line
                    if (rho_avg > threshold)
                    {
                        currentImage.Draw(new LineSegment2D(new Point(currentImage.Size.Width / 2, currentImage.Height / 2), new Point((int)(x_avg * 10) + currentImage.Size.Width / 2, (int)(y_avg * 10) + currentImage.Height / 2)), new Bgr(Color.Blue), 2);
                    }

                    //pull bitmap from image and draw to picture box
                    currentBitmap         = currentImage.Bitmap;
                    videoPictureBox.Image = currentBitmap;
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message + " " + exp.StackTrace);
            }

            perfSw.Stop();
            fps = ((double)framesProcessed / fpsSw.Elapsed.TotalSeconds);
            statusLabel.Text = framesProcessed.ToString() + " totalms: " + fpsSw.ElapsedMilliseconds.ToString() + " fps: " + ((double)framesProcessed / fpsSw.Elapsed.TotalSeconds).ToString() + " perfms: " + perfSw.ElapsedMilliseconds + " vmag: " + rho + " vang: " + theta_deg;
        }
コード例 #10
0
        private void StartMatching()
        {
            Image <Bgr, Byte>   target                       = Image_Target.Clone().Resize(scale, Inter.Linear);
            Image <Bgr, Byte>   texture                      = Image_Texture.Clone();
            Image <Gray, Byte>  target_gray                  = target.Convert <Gray, Byte>();
            Image <Gray, Byte>  texture_gray                 = texture.Convert <Gray, Byte>();
            Image <Gray, Byte>  target_hist_matched          = new Image <Gray, Byte>(target.Size);
            Image <Gray, Byte>  target_hist_matched_weighted = new Image <Gray, Byte>(target.Size);
            Image <Gray, float> target_sobel_x               = target_gray.Sobel(1, 0, 3);
            Image <Gray, float> target_sobel_y               = target_gray.Sobel(0, 1, 3);
            Image <Gray, float> texture_sobel_x              = texture_gray.Sobel(1, 0, 3);
            Image <Gray, float> texture_sobel_y              = texture_gray.Sobel(0, 1, 3);
            Image <Gray, float> target_sobel_mag             = new Image <Gray, float>(target_gray.Size);
            Image <Gray, float> texture_sobel_mag            = new Image <Gray, float>(texture_gray.Size);

            Image_Result          = new Image <Bgr, byte>(target.Width, target.Height, new Bgr(0, 0, 0));
            imageBox_Result.Image = Image_Result;

            this.Invoke(new MethodInvoker(() =>
            {
                progressBar_match.Value   = 0;
                progressBar_match.Maximum = (target.Width / size) * (target.Height / size);
            }));

            Matrix <byte> histLUT      = new Matrix <byte>(1, 256);
            Mat           hist_target  = new Mat();
            Mat           hist_texture = new Mat();

            VectorOfMat vm_target  = new VectorOfMat();
            VectorOfMat vm_texture = new VectorOfMat();

            vm_target.Push(target_gray);
            vm_texture.Push(texture_gray);

            CvInvoke.CalcHist(vm_target, new int[] { 0 }, null, hist_target, new int[] { 256 }, new float[] { 0, 255 }, false);
            CvInvoke.CalcHist(vm_texture, new int[] { 0 }, null, hist_texture, new int[] { 256 }, new float[] { 0, 255 }, false);

            float[] CDF_hist_target  = new float[256];
            float[] CDF_hist_texture = new float[256];
            Marshal.Copy(hist_target.DataPointer, CDF_hist_target, 0, 256);
            Marshal.Copy(hist_texture.DataPointer, CDF_hist_texture, 0, 256);

            for (int i = 1; i < 256; i++)
            {
                CDF_hist_target[i]  += CDF_hist_target[i - 1];
                CDF_hist_texture[i] += CDF_hist_texture[i - 1];
            }

            for (int i = 0; i < 256; i++)
            {
                histLUT.Data[0, i] = 0;
                for (int j = 0; j < 256; j++)
                {
                    if (CDF_hist_texture[j] >= CDF_hist_target[i])
                    {
                        histLUT.Data[0, i] = (byte)j;
                        break;
                    }
                }
            }
            CvInvoke.LUT(target_gray, histLUT, target_hist_matched);
            target_hist_matched_weighted = target_hist_matched * weight_hist + target_gray * (1.0 - weight_hist);

            CvInvoke.CartToPolar(target_sobel_x, target_sobel_y, target_sobel_mag, new Mat());
            CvInvoke.CartToPolar(texture_sobel_x, texture_sobel_y, texture_sobel_mag, new Mat());


            List <Matrix <float> > transformation_matrixs        = new List <Matrix <float> >();
            List <Matrix <float> > transformation_matrixs_invert = new List <Matrix <float> >();
            List <RectangleF>      rotatedRects = new List <RectangleF>();

            for (int i = 1; i < rotations; i++)
            {
                double         angle                        = i * (360.0 / (float)rotations);
                RectangleF     rotatedRect                  = new RotatedRect(new PointF(), texture.Size, (float)angle).MinAreaRect();
                PointF         center                       = new PointF(0.5f * texture.Width, 0.5f * texture.Height);
                Matrix <float> transformation_matrix        = new Matrix <float>(2, 3);
                Matrix <float> transformation_matrix_invert = new Matrix <float>(2, 3);
                CvInvoke.GetRotationMatrix2D(center, angle, 1.0, transformation_matrix);

                transformation_matrix.Data[0, 2] += (rotatedRect.Width - texture.Width) / 2;
                transformation_matrix.Data[1, 2] += (rotatedRect.Height - texture.Height) / 2;
                CvInvoke.InvertAffineTransform(transformation_matrix, transformation_matrix_invert);
                transformation_matrixs.Add(transformation_matrix);
                transformation_matrixs_invert.Add(transformation_matrix_invert);
                rotatedRects.Add(rotatedRect);
            }

            List <Image <Bgr, byte> > texture_rotations = new List <Image <Bgr, byte> >(rotations)
            {
            };
            List <Image <Gray, byte> > texture_gray_rotations = new List <Image <Gray, byte> >(rotations)
            {
            };
            List <Image <Gray, float> > texture_sobel_rotations = new List <Image <Gray, float> >(rotations)
            {
            };
            List <Image <Gray, byte> > texture_mask_rotations = new List <Image <Gray, byte> >(rotations)
            {
            };

            texture_rotations.Add(texture);
            texture_gray_rotations.Add(texture_gray);
            texture_sobel_rotations.Add(texture_sobel_mag);
            texture_mask_rotations.Add(new Image <Gray, byte>(texture.Width, texture.Height, new Gray(255)));
            for (int i = 1; i < rotations; i++)
            {
                texture_mask_rotations.Add(new Image <Gray, byte>(rotatedRects[i - 1].Size.ToSize()));
                texture_rotations.Add(new Image <Bgr, byte>(rotatedRects[i - 1].Size.ToSize()));
                texture_gray_rotations.Add(new Image <Gray, byte>(rotatedRects[i - 1].Size.ToSize()));
                texture_sobel_rotations.Add(new Image <Gray, float>(rotatedRects[i - 1].Size.ToSize()));
            }
            for (int i = 1; i < rotations; i++)
            {
                CvInvoke.WarpAffine(texture, texture_rotations[i], transformation_matrixs[i - 1], rotatedRects[i - 1].Size.ToSize(), Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(0));
                CvInvoke.WarpAffine(texture_gray, texture_gray_rotations[i], transformation_matrixs[i - 1], rotatedRects[i - 1].Size.ToSize(), Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(0));
                CvInvoke.WarpAffine(texture_sobel_mag, texture_sobel_rotations[i], transformation_matrixs[i - 1], rotatedRects[i - 1].Size.ToSize(), Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(0));
                CvInvoke.WarpAffine(texture_mask_rotations[0], texture_mask_rotations[i], transformation_matrixs[i - 1], rotatedRects[i - 1].Size.ToSize(), Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(0));
            }

            // Directory.SetCurrentDirectory(path);
            String current_path = path + @"\matched_patches";

            if (Directory.Exists(current_path))
            {
                DirectoryInfo di = new DirectoryInfo(current_path);
                foreach (FileInfo file in di.GetFiles())
                {
                    file.Delete();
                }
                foreach (DirectoryInfo dir in di.GetDirectories())
                {
                    dir.Delete(true);
                }
            }
            else
            {
                DirectoryInfo di = Directory.CreateDirectory(current_path);
            }

            for (int y = 0; y < target_hist_matched_weighted.Height / size; y++)
            {
                for (int x = 0; x < target_hist_matched_weighted.Width / size; x++)
                {
                    Image <Bgr, byte>   template;
                    Image <Gray, byte>  template_gray;
                    Image <Gray, float> template_sobel;

                    template           = target.Clone();
                    template_gray      = target_hist_matched_weighted.Clone();
                    template_sobel     = target_sobel_mag.Clone();
                    template.ROI       = new Rectangle(x * size, y * size, size, size);
                    template_gray.ROI  = new Rectangle(x * size, y * size, size, size);
                    template_sobel.ROI = new Rectangle(x * size, y * size, size, size);
                    template           = template.Clone();
                    template_gray      = template_gray.Copy();
                    template_sobel     = template_sobel.Copy();

                    int    minMatchIndex = -1;
                    double minMatchValue = double.MaxValue;
                    Point  minMatchLoc   = new Point();
                    Object _lock         = new Object();
                    Parallel.For(0, rotations, i =>
                    {
                        Image <Gray, float> match_gray  = new Image <Gray, float>(texture_gray.Size);
                        Image <Gray, float> match_sobel = new Image <Gray, float>(texture_sobel_mag.Size);
                        Image <Gray, float> match_sum   = new Image <Gray, float>(texture.Size);
                        double minVal = 0, maxVal = 0;
                        Point minLoc  = new Point(), maxLoc = new Point();

                        CvInvoke.MatchTemplate(texture_gray_rotations[i], template_gray, match_gray, TemplateMatchingType.Sqdiff);
                        CvInvoke.MatchTemplate(texture_sobel_rotations[i], template_sobel, match_sobel, TemplateMatchingType.Sqdiff);
                        match_sum = match_gray + match_sobel;
                        //CvInvoke.MinMaxLoc(match_sum, ref minVal, ref maxVal, ref minLoc, ref maxLoc);
                        //CudaInvoke.MinMaxLoc(match_sum, ref minVal, ref maxVal, ref minLoc, ref maxLoc, GetMinMaxLocMask(texture_mask_rotations[i], size));
                        CvInvoke.MinMaxLoc(match_sum, ref minVal, ref maxVal, ref minLoc, ref maxLoc, GetMinMaxLocMask(texture_mask_rotations[i], size));
                        lock (_lock)
                        {
                            if (minVal < minMatchValue && minVal > 0)
                            {
                                minMatchValue = minVal;
                                minMatchIndex = i;
                                minMatchLoc   = minLoc;
                            }
                        }
                        match_gray.Dispose();
                        match_sobel.Dispose();
                        match_sum.Dispose();
                    });
                    Console.WriteLine($"minMatchValue = {minMatchValue}\r\nminMatchIndex = {minMatchIndex}\r\nminMatchLoc = {minMatchLoc}");
                    if (minMatchIndex < 0)
                    {
                        MessageBox.Show("Out of textures!!!!");
                        return;
                    }
                    texture_mask_rotations[minMatchIndex].Draw(new Rectangle(minMatchLoc.X, minMatchLoc.Y, size - 1, size - 1), new Gray(0), -1);
                    if (minMatchIndex > 0)
                    {
                        Image <Gray, byte> mask = new Image <Gray, byte>(texture_mask_rotations[0].Size);
                        CvInvoke.WarpAffine(texture_mask_rotations[minMatchIndex], mask, transformation_matrixs_invert[minMatchIndex - 1], mask.Size, Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(0));
                        texture_mask_rotations[0] = texture_mask_rotations[0] - (255 - mask);
                    }
                    for (int i = 1; i < rotations; i++)
                    {
                        Image <Gray, byte> mask_rot = new Image <Gray, byte>(texture_mask_rotations[i].Size);
                        CvInvoke.WarpAffine(texture_mask_rotations[0], mask_rot, transformation_matrixs[i - 1], mask_rot.Size, Inter.Nearest, Warp.Default, BorderType.Constant, new MCvScalar(0));
                        mask_rot.CopyTo(texture_mask_rotations[i]);
                    }

                    texture_rotations[minMatchIndex].ROI = new Rectangle(minMatchLoc, new Size(size, size));
                    CvInvoke.Imwrite($@"{current_path}\{x}_{y}.bmp", texture_rotations[minMatchIndex].Copy());
                    imageBox_match.Image    = texture_rotations[minMatchIndex].Copy();
                    imageBox_template.Image = template.Copy();
                    Image_Result.ROI        = new Rectangle(x * size, y * size, size, size);
                    texture_rotations[minMatchIndex].CopyTo(Image_Result);

                    Image_Result.ROI = Rectangle.Empty;
                    texture_rotations[minMatchIndex].ROI = Rectangle.Empty;

                    imageBox_Result.Image = Image_Result;


                    if (minMatchIndex > 0)
                    {
                        PointF[] maskPoints     = { minMatchLoc, new PointF(minMatchLoc.X + size - 1, minMatchLoc.Y), new PointF(minMatchLoc.X, minMatchLoc.Y + size - 1), new PointF(minMatchLoc.X + size - 1, minMatchLoc.Y + size - 1) };
                        PointF[] maskPoints_rot = new PointF[4];
                        for (int i = 0; i < 4; i++)
                        {
                            maskPoints_rot[i].X = maskPoints[i].X * transformation_matrixs_invert[minMatchIndex - 1].Data[0, 0] + maskPoints[i].Y * transformation_matrixs_invert[minMatchIndex - 1].Data[0, 1] + 1.0f * transformation_matrixs_invert[minMatchIndex - 1].Data[0, 2];
                            maskPoints_rot[i].Y = maskPoints[i].X * transformation_matrixs_invert[minMatchIndex - 1].Data[1, 0] + maskPoints[i].Y * transformation_matrixs_invert[minMatchIndex - 1].Data[1, 1] + 1.0f * transformation_matrixs_invert[minMatchIndex - 1].Data[1, 2];
                        }
                        Point[] maskPoints_rot_round = { Point.Round(maskPoints_rot[0]), Point.Round(maskPoints_rot[1]), Point.Round(maskPoints_rot[3]), Point.Round(maskPoints_rot[2]) };
                        texture.FillConvexPoly(maskPoints_rot_round, new Bgr(0, 0, 0));
                    }
                    else
                    {
                        //texture.DrawPolyline(new Point[] { minMatchLoc, new Point(minMatchLoc.X + size, minMatchLoc.Y), new Point(minMatchLoc.X + size, minMatchLoc.Y + size), new Point(minMatchLoc.X, minMatchLoc.Y + size) }, true, new Bgr(0, 0, 0), 0);
                        texture.Draw(new Rectangle(minMatchLoc, new Size(size - 1, size - 1)), new Bgr(0, 0, 0), -1);
                    }
                    imageBox_Texture.Image = texture;

                    template.Dispose();
                    template_gray.Dispose();
                    template_sobel.Dispose();
                    GC.Collect();

                    this.Invoke(new MethodInvoker(() =>
                    {
                        progressBar_match.Value++;
                    }));
                }
            }
        }
コード例 #11
0
        private void OpticalFlowEvent(ImageProcess sender, Mat mat)
        {
            if (cnt == 0)
            {
                //cnt ==0, clone mat for previous mat

                prevMat = mat.Clone();
                cnt++;
                return;
            }


            Image <Emgu.CV.Structure.Gray, byte> prev_img = prevMat.ToImage <Emgu.CV.Structure.Gray, byte>();
            Image <Emgu.CV.Structure.Gray, byte> curr_img = mat.ToImage <Emgu.CV.Structure.Gray, byte>();

            Mat flow = new Mat(prev_img.Height, prev_img.Width, DepthType.Cv32F, 2);

            CvInvoke.CalcOpticalFlowFarneback(prev_img, curr_img, flow, 0.5, 3, 15, 3, 6, 1.3, 0);

            Mat[] flow_parts = new Mat[2];
            flow_parts = flow.Split();
            Mat magnitude = new Mat(), angle = new Mat(), magn_norm = new Mat();

            CvInvoke.CartToPolar(flow_parts[0], flow_parts[1], magnitude, angle, true);
            CvInvoke.Normalize(magnitude, magn_norm, 0.0, 1.0, NormType.MinMax);

            /*
             * //start drawing
             * float factor = (float)((1.0 / 360.0) * (180.0 / 255.0));
             * Mat colorAngle = angle * factor;
             * //angle *= ((1f / 360f) * (180f / 255f));
             * //build hsv image
             * Mat[]  _hsv= new Mat[3];
             * Mat hsv = new Mat();
             * Mat hsv8 = new Mat();
             * Mat bgr = new Mat();
             * _hsv[0] = colorAngle;
             * _hsv[1] = Mat.Ones(colorAngle.Height,angle.Width,DepthType.Cv32F,1);
             * _hsv[2] = magn_norm;
             * VectorOfMat vm = new VectorOfMat(_hsv);
             * CvInvoke.Merge(vm, hsv);
             * hsv.ConvertTo(hsv8,DepthType.Cv8U, 255.0);
             * CvInvoke.CvtColor(hsv8, bgr,ColorConversion.Hsv2Bgr);
             * bgr.Save("opticalFlow.bmp");
             */
            List <double> offset = CalculateDirection(angle, magn_norm);

            Console.WriteLine(offset[0] + " , " + offset[1]);


            //test direction

            /*if( Math.Abs(offset[0]) >Math.Abs(offset[1]))
             * {
             *
             *  if (offset[0] > 0 )
             *  {
             *      Console.WriteLine("Right");
             *  }
             *  else
             *  {
             *      Console.WriteLine("Left");
             *  }
             *
             * }
             * else
             * {
             *
             *  if (offset[1] > 0)
             *  {
             *      Console.WriteLine("Down");
             *  }
             *  else
             *  {
             *      Console.WriteLine("Up");
             *  }
             *
             * }*/


            prevMat = mat.Clone();
        }
コード例 #12
0
ファイル: Methods.cs プロジェクト: rasberry/RasDenoise
        //Followed this source code mostly
        //https://github.com/opencv-java/fourier-transform/blob/master/src/it/polito/teaching/cv/FourierController.java
        public static void DFTForward(DFTArgs args)
        {
            var imgSrc = CvInvoke.Imread(args.src, ImreadModes.Grayscale | ImreadModes.AnyDepth);

            //get optimal dimensions (power of 2 i think..)
            int xdftsz = CvInvoke.GetOptimalDFTSize(imgSrc.Rows);
            int ydftsz = CvInvoke.GetOptimalDFTSize(imgSrc.Cols);

            //pad input image to optimal dimensions
            CvInvoke.CopyMakeBorder(imgSrc, imgSrc,
                                    0, xdftsz - imgSrc.Rows, 0, ydftsz - imgSrc.Cols,
                                    BorderType.Constant, new MCvScalar(0)
                                    );
            imgSrc.PrintInfo("1");

            //use 32F format for calcs
            imgSrc.ConvertTo(imgSrc, DepthType.Cv32F);
            imgSrc.PrintInfo("2");
            //create a 2 channel mat using the input as the fist channel
            var planes = new VectorOfMat();

            planes.Push(imgSrc);
            planes.Push(new Mat(imgSrc.Size, DepthType.Cv32F, 1));
            Mat complex = new Mat();

            CvInvoke.Merge(planes, complex);
            complex.PrintInfo("3");

            //do the fourrier transform
            CvInvoke.Dft(complex, complex, DxtType.Forward, 0);
            complex.PrintInfo("4");

            //split channels into real / imaginary
            var compos = new VectorOfMat(2);

            CvInvoke.Split(complex, compos);

            //convert real / imaginary to magnitude / phase - which is easier to deal with when looking for artifacts
            Mat mag = new Mat();
            Mat phs = new Mat();

            CvInvoke.CartToPolar(compos[0], compos[1], mag, phs);
            mag.PrintInfo("5m");

            //convert to log scale since magnitude tends to have a huge range
            Helpers.AddS(mag, 1.0, mag);
            CvInvoke.Log(mag, mag);
            mag.PrintInfo("6m");
            phs.PrintInfo("6p");

            //regular DFT puts low frequencies in the corners - this flips them to the center
            RearrangeQuadrants(mag);
            RearrangeQuadrants(phs);

            double magMax, magMin;

            CvInvoke.MinMaxIdx(mag, out magMin, out magMax, null, null);
            //Console.WriteLine("-mi "+magMin+","+magMax+"]");

            double phsMax, phsMin;

            CvInvoke.MinMaxIdx(phs, out phsMin, out phsMax, null, null);

            //convert to a 'normal' format and scale the data
            Mat magOut = new Mat();
            Mat phsOut = new Mat();

            CvInvoke.Normalize(mag, magOut, 0, 65535, NormType.MinMax, DepthType.Cv16U);
            CvInvoke.Normalize(phs, phsOut, 0, 65535, NormType.MinMax, DepthType.Cv16U);

            string name = Path.GetFileNameWithoutExtension(args.dst);

            magOut.PrintInfo("7m");
            phsOut.PrintInfo("7p");

            Console.WriteLine("-mi " + magMin + " -mx " + magMax + " -pi " + phsMin + " -px " + phsMax);

            magOut.Save(name + "-mag.png");
            phsOut.Save(name + "-phs.png");
        }
コード例 #13
0
        /// <summary>
        /// NCC to find template
        /// </summary>
        private void NCCExecute()
        {
            try
            {
                Trace.TraceInformation("NCC matching start");
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();

                Mat dst = destination.Clone();

                /// convert to gray image
                Mat grayImage = new Mat();
                CvInvoke.CvtColor(dst, grayImage, ColorConversion.Rgb2Gray);

                /// use the sobel filter on the source image which returns the gradients in the X (Gx) and Y (Gy) direction.
                Mat gx = new Mat();
                Mat gy = new Mat();
                CvInvoke.Sobel(grayImage, gx, DepthType.Cv64F, 1, 0);
                CvInvoke.Sobel(grayImage, gy, DepthType.Cv64F, 0, 1);

                /// compute the magnitude and direction
                Mat magnitude = new Mat();
                Mat direction = new Mat();
                CvInvoke.CartToPolar(gx, gy, magnitude, direction);

                /// template matching
                var _gx        = gx.ToImage <Gray, double>();
                var _gy        = gy.ToImage <Gray, double>();
                var _magnitude = magnitude.ToImage <Gray, double>();

                long   totalLength = contoursLength;
                double nMinScore   = minScore / totalLength; // normalized min score
                double nGreediness = (1 - greediness * minScore) / (1 - greediness) / totalLength;

                double partialScore = 0;
                double resultScore  = 0;
                int    resultX      = 0;
                int    resultY      = 0;
                for (int i = 0, h = grayImage.Height; i < h; i++)
                {
                    for (int j = 0, w = grayImage.Width; j < w; j++)
                    {
                        double sum = 0;
                        long   num = 0;
                        for (int m = 0, rank = contoursRelative.Size; m < rank; m++)
                        {
                            for (int n = 0, length = contoursRelative[m].Size; n < length; n++)
                            {
                                num += 1;
                                int curX = j + contoursRelative[m][n].X;
                                int curY = i + contoursRelative[m][n].Y;
                                if (curX < 0 || curY < 0 || curX > grayImage.Width - 1 || curY > grayImage.Height - 1)
                                {
                                    continue;
                                }

                                double sdx = _gx.Data[curY, curX, 0];
                                double sdy = _gy.Data[curY, curX, 0];
                                double tdx = contoursInfo[m][n].DerivativeX;
                                double tdy = contoursInfo[m][n].DerivativeY;

                                if ((sdy != 0 || sdx != 0) && (tdx != 0 || tdy != 0))
                                {
                                    double nMagnitude = _magnitude.Data[curY, curX, 0];
                                    if (nMagnitude != 0)
                                    {
                                        sum += (sdx * tdx + sdy * tdy) * contoursInfo[m][n].MagnitudeN / nMagnitude;
                                    }
                                }
                                partialScore = sum / num;
#if FAST
                                if (partialScore < minScore)
#else
                                if (partialScore < Math.Min((minScore - 1) + (nGreediness * num), nMinScore * num))
#endif
                                { break; }
                            }
                        }
                        if (partialScore > resultScore)
                        {
                            resultScore = partialScore;
                            resultX     = j;
                            resultY     = i;
                            Trace.TraceInformation($"Current Score : {resultScore}");
                        }
                    }
                }

                Trace.TraceInformation($"Score : {resultScore}");

                /// overlay display origin image, edge(green) and origin point(red)
                /// NOTE: origin point is the first edge point
                var point = new System.Drawing.Point(resultX, resultY);
                Trace.TraceInformation($"Point : {point}");
                CvInvoke.DrawContours(dst, contoursRelative, -1, new Bgr(System.Drawing.Color.Green).MCvScalar, 5, offset: point);
                CvInvoke.Circle(dst, point, 2, new Bgr(System.Drawing.Color.Red).MCvScalar, -1);
                grayImage.Dispose();
                Destination.Dispose();
                Destination = dst;

                Trace.TraceInformation($"NCC matching end. time: {(double)stopwatch.ElapsedTicks * 1000 / Stopwatch.Frequency} ms");
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.Message);
                Trace.TraceError(ex.StackTrace);
            }
        }
コード例 #14
0
        /// <summary>
        /// Create a template
        /// </summary>
        private void TemplateExecute()
        {
            try
            {
                contoursRelative = new VectorOfVectorOfPoint();
                contoursInfo     = new List <PointInfo[]>();
                contoursLength   = 0;

                /// clone origin image
                Mat src = template.Clone();

                /// convert to gray image
                Mat grayImage = new Mat();
                CvInvoke.CvtColor(src, grayImage, ColorConversion.Rgb2Gray);

                /// using the canny algorithm to get edges
                Mat output    = new Mat();
                Mat hierarchy = new Mat();
                VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
                CvInvoke.Canny(grayImage, output, 100, 800);
                CvInvoke.FindContours(output, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxNone);

                /// use the sobel filter on the template image which returns the gradients in the X (Gx) and Y (Gy) direction.
                Mat gx = new Mat();
                Mat gy = new Mat();
                CvInvoke.Sobel(grayImage, gx, DepthType.Cv64F, 1, 0);
                CvInvoke.Sobel(grayImage, gy, DepthType.Cv64F, 0, 1);

                /// compute the magnitude and direction
                Mat magnitude = new Mat();
                Mat direction = new Mat();
                CvInvoke.CartToPolar(gx, gy, magnitude, direction);

                /// save edge info
                var _gx        = gx.ToImage <Gray, double>();
                var _gy        = gy.ToImage <Gray, double>();
                var _magnitude = magnitude.ToImage <Gray, double>();

                double    magnitudeTemp = 0;
                PointInfo pointInfo     = new PointInfo();
                int       originx       = contours[0][0].X;
                int       originy       = contours[0][0].Y;
                for (int i = 0, m = contours.Size; i < m; i++)
                {
                    int n = contours[i].Size;
                    contoursLength += n;
                    contoursInfo.Add(new PointInfo[n]);
                    System.Drawing.Point[] points = new System.Drawing.Point[n];

                    for (int j = 0; j < n; j++)
                    {
                        int x = contours[i][j].X;
                        int y = contours[i][j].Y;
                        points[j].X           = x - originx;
                        points[j].Y           = y - originy;
                        pointInfo.DerivativeX = _gx.Data[y, x, 0];
                        pointInfo.DerivativeY = _gy.Data[y, x, 0];
                        magnitudeTemp         = _magnitude.Data[y, x, 0];
                        pointInfo.Magnitude   = magnitudeTemp;
                        if (magnitudeTemp != 0)
                        {
                            pointInfo.MagnitudeN = 1 / magnitudeTemp;
                        }
                        contoursInfo[i][j] = pointInfo;
                    }
                    contoursRelative.Push(new VectorOfPoint(points));
                }

                /// overlay display origin image, edge(green) and origin point(red)
                /// NOTE: origin point is the first edge point
                CvInvoke.DrawContours(src, contours, -1, new Bgr(System.Drawing.Color.Green).MCvScalar, 5);
                var point = new System.Drawing.Point(contours[0][0].X, contours[0][0].Y);
                CvInvoke.Circle(src, point, 2, new Bgr(System.Drawing.Color.Red).MCvScalar, -1);
                gx.Dispose();
                _gx.Dispose();
                gy.Dispose();
                _gy.Dispose();
                magnitude.Dispose();
                _magnitude.Dispose();
                direction.Dispose();
                Template.Dispose();
                Template = src;
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.Message);
                Trace.TraceError(ex.StackTrace);
            }
        }
コード例 #15
0
        private void HOG()
        {
            Image <Gray, byte>  slika  = My_ImageRecieve.Convert <Gray, byte>();
            Image <Gray, float> photoX = slika.Sobel(1, 0, 1);
            Image <Gray, float> photoY = slika.Sobel(0, 1, 1);

            Image <Gray, float> magnitude = new Image <Gray, float>(slika.Size); //magnitude spremenljivka za sliko
            Image <Gray, float> direction = new Image <Gray, float>(slika.Size); //spremenljivka za kote

            var binsMat = new float[5000, 10000][];

            binType[,] beansMat = new binType[5000, 10000];
            List <List <float[]> > biniMat2d = new List <List <float[]> >();
            List <float[]>         biniMat1d = new List <float[]>();

            CvInvoke.CartToPolar(photoX, photoY, magnitude, direction, true);

            //pretvorba iz 0-360 v 0-180
            for (int i = 0; i < direction.Height; i++)
            {
                for (int j = 0; j < direction.Width; j++)
                {
                    int temp = (int)direction.Data[i, j, 0];
                    temp = temp - 360;
                    if (temp < 0)
                    {
                        temp = temp * -1;
                    }
                    direction.Data[i, j, 0] = (byte)temp;
                }
            }
            //konec pretvorbe

            pictureBox5.Image = direction.ToBitmap();

            int[,] celica = new int[8, 8];


            for (int x = 0; x < direction.Height - 8; x = x + 8)
            {
                if (direction.Height - x >= 1)
                {
                    currentbinMatY = binMatY;
                    Console.WriteLine(binMatY);
                    binMatY = 0;
                    for (int y = 0; y < direction.Width - 8; y = y + 8)
                    {
                        if (direction.Width - y >= 1)
                        {
                            for (int i = 0; i < 8; i++)
                            {
                                for (int j = 0; j < 8; j++)
                                {
                                    bins         = new float[9];
                                    celica[i, j] = (int)direction.Data[x + i, y + j, 0];

                                    if (celica[i, j] == 0 || celica[i, j] == 180)//0 ali 180 je enako //POLNI BIN
                                    {
                                        bins[0] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 0 && celica[i, j] < 20)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 0;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 10)
                                        {
                                            bins[0] = getMag * part2;
                                            bins[1] = getMag * part;
                                        }
                                        else if (celica[i, j] > 10)
                                        {
                                            bins[0] = getMag * part;
                                            bins[1] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[0] = getMag * part;
                                            bins[1] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 20)//POLNI BIN
                                    {
                                        bins[1] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 20 && celica[i, j] < 40)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 20;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 30)
                                        {
                                            bins[1] = getMag * part2;
                                            bins[2] = getMag * part;
                                        }
                                        else if (celica[i, j] > 30)
                                        {
                                            bins[1] = getMag * part;
                                            bins[2] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[1] = getMag * part;
                                            bins[2] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 40)//POLNI BIN
                                    {
                                        bins[2] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 40 && celica[i, j] < 60)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 40;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 50)
                                        {
                                            bins[2] = getMag * part2;
                                            bins[3] = getMag * part;
                                        }
                                        else if (celica[i, j] > 50)
                                        {
                                            bins[2] = getMag * part;
                                            bins[3] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[2] = getMag * part;
                                            bins[3] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 60)//POLNI BIN
                                    {
                                        bins[3] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 60 && celica[i, j] < 80)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 60;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 70)
                                        {
                                            bins[3] = getMag * part2;
                                            bins[4] = getMag * part;
                                        }
                                        else if (celica[i, j] > 70)
                                        {
                                            bins[3] = getMag * part;
                                            bins[4] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[3] = getMag * part;
                                            bins[4] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 80)//POLNI BIN
                                    {
                                        bins[4] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 80 && celica[i, j] < 100)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 80;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 90)
                                        {
                                            bins[4] = getMag * part2;
                                            bins[5] = getMag * part;
                                        }
                                        else if (celica[i, j] > 90)
                                        {
                                            bins[4] = getMag * part;
                                            bins[5] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[4] = getMag * part;
                                            bins[5] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 100)//POLNI BIN
                                    {
                                        bins[5] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 100 && celica[i, j] < 120)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 100;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        Console.WriteLine(magnitude.Data[x + i, y + j, 0]);
                                        if (celica[i, j] < 110)
                                        {
                                            bins[5] = getMag * part2;
                                            bins[6] = getMag * part;
                                        }
                                        else if (celica[i, j] > 110)
                                        {
                                            bins[5] = getMag * part;
                                            bins[6] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[5] = getMag * part;
                                            bins[6] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 120)//POLNI BIN
                                    {
                                        bins[6] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 120 && celica[i, j] < 140)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 120;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 130)
                                        {
                                            bins[6] = getMag * part2;
                                            bins[7] = getMag * part;
                                        }
                                        else if (celica[i, j] > 130)
                                        {
                                            bins[6] = getMag * part;
                                            bins[7] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[6] = getMag * part;
                                            bins[7] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 140)//POLNI BIN
                                    {
                                        bins[7] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 140 && celica[i, j] < 160)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 140;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 150)
                                        {
                                            bins[7] = getMag * part2;
                                            bins[8] = getMag * part;
                                        }
                                        else if (celica[i, j] > 150)
                                        {
                                            bins[7] = getMag * part;
                                            bins[8] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[7] = getMag * part;
                                            bins[8] = getMag * part2;
                                        }
                                    }
                                    else if (celica[i, j] == 160)//POLNI BIN
                                    {
                                        bins[8] = (float)magnitude.Data[x + i, y + j, 0];
                                    }
                                    else if (celica[i, j] > 160 && celica[i, j] < 180)//RAZDELITEV MED SOSEDE
                                    {
                                        int   tmpDir  = celica[i, j];
                                        float subLbin = tmpDir - 160;
                                        float part    = subLbin / 20;
                                        float part2   = 1 - part;

                                        float getMag = (float)magnitude.Data[x + i, y + j, 0];
                                        if (celica[i, j] < 170)
                                        {
                                            bins[8] = getMag * part2;
                                            bins[0] = getMag * part;
                                        }
                                        else if (celica[i, j] > 170)
                                        {
                                            bins[8] = getMag * part;
                                            bins[0] = getMag * part2;
                                        }
                                        else
                                        {
                                            bins[8] = getMag * part;
                                            bins[0] = getMag * part2;
                                        }
                                    }
                                } //j celica
                            }     //i celica
                            biniMat1d.Add(bins);//list
                            beansMat[binMatX, binMatY].beans = bins;//probamo z strukturo
                            binsMat[binMatX, binMatY]        = bins; //2d array of arrays
                            //Console.Write(beansMat[binMatX, binMatY].beans);
                            binMatY++;                               //++ y coordinate of 2d array of arrays
                        }//znotraj ifa za lego [i,j]WIDTH
                    }//direction width
                    biniMat2d.Add(biniMat1d); //list
                    binMatX++;                //++ x coordinate of 2d array of arrays
                }//znotraj ifa za lego [i,j]HEIGHT
            }//direction height
            Console.WriteLine("________");
            float[] temp1 = new float[9];
            for (int i = 0; i < binMatX - 1; i++)     //-1 ker bomo z x + x+1 vedno pogledali z predzadnjim tudi zadnjega v x in y smeri
            {
                for (int j = 0; j < binMatY - 1; j++) //-||-
                {
                    Console.WriteLine("[" + i + "," + j + "]  = ");
                    //Console.WriteLine(beansMat[i, j].beans);
                    temp1 = beansMat[i, j].beans;
                    for (int k = 0; k < 9; k++)
                    {
                        Console.Write(temp1[k]);
                    }
                    Console.WriteLine(".");
                } //end of Y
            }     //end of X
            Console.WriteLine("______________");
            //prepare cells for storage of bins for each cell and 1 blockBins that will concatenate 4 cells into 1 blockbin(4bins->1bin)
            float[] cell1     = new float[9];
            float[] cell2     = new float[9];
            float[] cell3     = new float[9];
            float[] cell4     = new float[9];
            float[] blockBins = new float[37];
            int     blockBinC = 0;//counter

            float[] concatBlockBinsNormalized  = new float[binMatX * binMatY * 36];
            int     concatBlockBinsNormalizedC = 0;//counter
            //prepare a SortedDictionary TODO
            Dictionary <float, int> dictionary = new Dictionary <float, int>();

            for (int i = 0; i < binMatX - 1; i++)     //-1 ker bomo z x + x+1 vedno pogledali z predzadnjim tudi zadnjega v x in y smeri
            {
                for (int j = 0; j < binMatY - 1; j++) //-||-
                {
                    //cell1 = binsMat[i, j];
                    cell1 = beansMat[i, j].beans;
                    for (int l = 0; l < 9; l++)
                    {
                        Console.Write(cell1[l]);
                    }//console wrrite test
                    Console.WriteLine(".");
                    for (int l = 0; l < 9; l++)
                    {
                        blockBins[blockBinC] = cell1[l];
                        blockBinC++;
                    }//go through floats in each cell and copy them to blockBins
                    //cell2 = binsMat[i, j+1];
                    cell2 = beansMat[i, j + 1].beans;
                    for (int l = 0; l < 9; l++)
                    {
                        blockBins[blockBinC] = cell2[l];
                        blockBinC++;
                    }//go through floats in each cell and copy them to blockBins
                    //cell3 = binsMat[i+1, j];
                    cell3 = beansMat[i + 1, j].beans;
                    for (int l = 0; l < 9; l++)
                    {
                        blockBins[blockBinC] = cell3[l];
                        blockBinC++;
                    }//go through floats in each cell and copy them to blockBins
                    //cell4 = binsMat[i+1, j+1];
                    cell4 = beansMat[i + 1, j + 1].beans;
                    for (int l = 0; l < 9; l++)
                    {
                        blockBins[blockBinC] = cell4[l];
                        blockBinC++;
                    }//go through floats in each cell and copy them to blockBins

                    //normalizacija blockBins:
                    float[] blockBinsNormalized = new float[37];
                    float   suma = 0;
                    for (int k = 0; k < 37; k++)//racunanje skale
                    {
                        suma = suma + (blockBins[k] * blockBins[k]);
                    }
                    float scale = (float)Math.Sqrt(suma); //skala
                    for (int k = 0; k < 37; k++)          //normalizacija blockBins*scale -> blockBinsNormalized
                    {
                        blockBinsNormalized[k] = blockBins[k] * scale;
                    }
                    for (int k = 0; k < 37; k++)//zlivanje v koncni vector vseh vrednosti
                    {
                        concatBlockBinsNormalized[concatBlockBinsNormalizedC] = blockBinsNormalized[k];
                        concatBlockBinsNormalizedC++;
                    }
                    blockBinC = 0;
                } //end of Y
            }     //end of X
            //izdelava slovarja
            for (int i = 0; i < concatBlockBinsNormalizedC; i++)//zlivanje v koncni vector vseh vrednosti
            {
                // See whether it contains this string.
                if (!dictionary.ContainsKey(concatBlockBinsNormalized[i]))
                {
                    dictionary.Add(concatBlockBinsNormalized[i], 1);
                }
                if (dictionary.ContainsKey(concatBlockBinsNormalized[i]))
                {
                    dictionary[concatBlockBinsNormalized[i]]++;
                }
            }
            foreach (KeyValuePair <float, int> pair in dictionary)
            {
                Console.WriteLine("{0}, {1}", pair.Key, pair.Value);
            }
        }
        /// <summary>
        /// get the motion influence map from the processed frames.
        /// </summary>
        /// <param name="vid">Path of the video.</param>
        /// <param name="xBlockSize">Horizontal size of the block of the block.</param>
        /// <param name="yBlockSize">Vertical size of the block of the block.</param>
        /// <param name="noOfRowInBlock">'Number of rows of the mega grid.</param>
        /// <param name="noOfColInBlock">Number of columns of the mega gird.</param>
        /// <param name="total_frames">Total frames that we will process.</param>
        /// <param name="clustering">Boolean to determinate wherher to cluster later or not</param>
        /// <param name="frame_nr">Number of the starting frame.</param>
        /// <returns>Motion influence map.</returns>
        public List <double[][][]> get_motion_influence_map(String vid, out int xBlockSize, out int yBlockSize, out int noOfRowInBlock, out int noOfColInBlock, out int total_frames, bool clustering, int frame_nr = 0)
        {
            List <double[][][]> ret = new List <double[][][]>();

            xBlockSize     = 0;
            yBlockSize     = 0;
            noOfRowInBlock = 0;
            noOfColInBlock = 0;
            total_frames   = 0;

            try
            {
                mag        = new Mat();
                ang        = new Mat();
                frame      = new Mat();
                prev_frame = new Mat();
                cap        = new VideoCapture(vid);
                if (!clustering)
                {
                    total_frames = 3;
                }
                else
                {
                    total_frames = Convert.ToInt32(cap.GetCaptureProperty(CapProp.FrameCount));
                }
                cap.SetCaptureProperty(CapProp.PosFrames, frame_nr);
                frame      = cap.QueryFrame();
                prev_frame = frame;
            }
            catch (NullReferenceException except)
            {
                Console.WriteLine(except.Message);
            }

            int mm = 0;

            Console.WriteLine("Total Frames : {0}", total_frames);

            while (mm < total_frames - 1)
            {
                Console.WriteLine("Frame : " + frame_nr);
                prev_frame = frame;
                frame_nr  += 1;
                cap.SetCaptureProperty(CapProp.PosFrames, frame_nr);
                frame = cap.QueryFrame();

                Image <Gray, Byte> prev_grey_img = new Image <Gray, byte>(frame.Width, frame.Height);
                Image <Gray, Byte> curr_grey_img = new Image <Gray, byte>(frame.Width, frame.Height);

                Image <Gray, float> flow_x = new Image <Gray, float>(frame.Width, frame.Height);
                Image <Gray, float> flow_y = new Image <Gray, float>(frame.Width, frame.Height);

                curr_grey_img = frame.ToImage <Gray, byte>();
                prev_grey_img = prev_frame.ToImage <Gray, Byte>();


                CvInvoke.CalcOpticalFlowFarneback(prev_grey_img, curr_grey_img, flow_x, flow_y, 0.5, 3, 15, 3, 6, 1.3, 0);
                CvInvoke.CartToPolar(flow_x, flow_y, mag, ang);

                OptFlowOfBlocks.calcOptFlowOfBlocks(mag, ang, curr_grey_img, out opFlowOfBlocks, out centreOfBlocks,
                                                    out rows, out cols, out noOfRowInBlock, out noOfColInBlock, out xBlockSize, out yBlockSize, out blockSize);
                motionInMapGenerator(opFlowOfBlocks, blockSize, centreOfBlocks, xBlockSize, yBlockSize, out motionInfVal);

                ret.Add(motionInfVal);

                mm++;
            }
            return(ret);
        }