GpuInvoke vs CvInvoke

asked 2015-04-30 10:14:32 -0500

Wes gravatar image

Specs:

IDE: Visual Studio Premium 2013

Language: C#

OpenCV: EmguCV v.2.4.2.1777

GPU: GeForce GTS 250

CPU: Intel Core i7-930

I'm seeing an issue where the CPU results seem to be more accurate than the GPU results using the same settings. Am I setting this up wrong or is this expected?

Variable setup:

        Image<Emgu.CV.Structure.Bgr, byte> scene_img = new Image<Emgu.CV.Structure.Bgr, byte>(scene_org);
        Image<Emgu.CV.Structure.Bgr, byte> match_img = new Image<Emgu.CV.Structure.Bgr, byte>(match_org);

        GpuImage<Emgu.CV.Structure.Bgr, byte> scene_gpu = new GpuImage<Emgu.CV.Structure.Bgr, byte>(scene_img);
        GpuImage<Emgu.CV.Structure.Bgr, byte> match_gpu = new GpuImage<Emgu.CV.Structure.Bgr, byte>(match_img);

        GpuImage<Emgu.CV.Structure.Gray, float> result_gpu =
            new GpuImage<Emgu.CV.Structure.Gray, float>(
                (scene_img.Width - match_img.Width) + 1, (scene_img.Height - match_img.Height) + 1
            );

        Point minLoc = new Point(), maxLoc = new Point();
        double minVal = 0, maxVal = 0;

GPU Code:

        GpuInvoke.MatchTemplate(scene_gpu, match_gpu, result_gpu, TM_TYPE.CV_TM_CCOEFF_NORMED, IntPtr.Zero, IntPtr.Zero);
        GpuInvoke.MinMaxLoc(result_gpu, ref minVal, ref maxVal, ref minLoc, ref maxLoc, IntPtr.Zero);
        Console.WriteLine("minVal: " + minVal.ToString() + " maxVal: " + maxVal.ToString() + " minLoc: " + minLoc.ToString()
            + " maxLoc: " + maxLoc.ToString());

CPU Code:

       Emgu.CV.Image<Emgu.CV.Structure.Gray, float> result_img =
            new Image<Emgu.CV.Structure.Gray, float>(
                (scene_img.Width - match_img.Width) + 1, (scene_img.Height - match_img.Height) + 1
        );
        Emgu.CV.CvInvoke.cvMatchTemplate(scene_img, match_img, result_img, TM_TYPE.CV_TM_CCOEFF_NORMED);
        Emgu.CV.CvInvoke.cvMinMaxLoc(result_img, ref minVal, ref maxVal, ref minLoc, ref maxLoc, IntPtr.Zero);
        Console.WriteLine("minVal: " + minVal.ToString() + " maxVal: " + maxVal.ToString() + " minLoc: " + minLoc.ToString()
            + " maxLoc: " + maxLoc.ToString());

GPU Results:

minVal: 0 maxVal: 0 minLoc: {X=224,Y=208} maxLoc: {X=224,Y=208}

CPU Results:

minVal: -0.199123710393906 maxVal: 1 minLoc: {X=1573,Y=9} maxLoc: {X=1360,Y=44}

edit retag flag offensive close merge delete

Comments

rather ask on http://www.emgu.com/forum/ (we can't help with 3rd party wrappers)

berak gravatar imageberak ( 2015-04-30 10:27:45 -0500 )edit

Thanks for the recommendation. I went ahead and created a topic over there as well. I'm completely fine with converting to C# code if anyone would like to leave an example of how to solve what I think is going on here.

It looks like the MinMaxLoc function returns an occurrence in a larger collection and it looks like the return for that in the GPU classes aren't necessarily ordered the same way it is when using CvInvoke.

So, my question is how can I iterate over the matched results and compare the "score" to some threshold value?

Basically what I need to do is find all occurrences of an image in a larger set and I'd like to do it using the GPU.

Wes gravatar imageWes ( 2015-05-01 09:51:57 -0500 )edit

Lets ignore the C# wrapper for a while. I've seen examples of matching with multiple occurrences using the CPU and OpenCV, example URL below. https://opencv-code.com/quick-tips/ho...

How is the floodFill method achieved using the GPU?

Wes gravatar imageWes ( 2015-05-01 13:07:45 -0500 )edit

sorry, totally misread your post.

berak gravatar imageberak ( 2015-05-01 14:49:53 -0500 )edit