Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more: , +
I try to find the five smaller shapes among many shapes but my program doesn't work well, can you tell me where is the problem

What I have tried:

Image<Gray, byte> imgOutput = imgInput.Convert<Gray, byte>();
            binary = new Image<Gray, byte>(imgInput.Width, imgInput.Height, new Gray(0));
            CvInvoke.AdaptiveThreshold(imgOutput, binary, 255, Emgu.CV.CvEnum.AdaptiveThresholdType.GaussianC, Emgu.CV.CvEnum.ThresholdType.Binary, 5, 0.0);

            Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();

            Mat hier = new Mat();

            CvInvoke.FindContours(binary, contours, hier,     Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
            Dictionary<int, double> dict = new Dictionary<int, double>();
            if (contours.Size > 0)
            {
                for (int i = 0; i < contours.Size; i++)
                {
                    double aera = CvInvoke.ContourArea(contours[i]);
                    Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);
                   
                        dict.Add(i, aera);
                    
                }
            }
            var item = dict.OrderBy(v => v.Value).Take(5);
           
            foreach (var it in item)
            {
                int key = int.Parse(it.Key.ToString());
                Rectangle rect = CvInvoke.BoundingRectangle(contours[key]);
                CvInvoke.Rectangle(imgInput, rect, new MCvScalar(255, 0, 0), 8);
                pictureBox2.Image = imgInput.Bitmap;

                
            }
        }
Posted
Updated 25-Sep-19 7:53am
Comments
Afzaal Ahmad Zeeshan 24-Sep-19 13:25pm    
5 smallest shapes in the list, or 5 shapes smaller than a size, or what?

A simple answer would be, list the shapes with their area, and then sort them in descending order based on their area, finally get the top 5.
Member 14129828 24-Sep-19 16:53pm    
thank you
BillWoodruff 24-Sep-19 22:12pm    
Hi Afzaal, I suggest you post this as a solution; appears to me to be all that's needed. I suspect the OP could also use a SortedDictionary here.
Member 14129828 25-Sep-19 11:30am    
Yes ... this is required and thanks for the answer
Afzaal Ahmad Zeeshan 25-Sep-19 13:54pm    
Hi Bill, I posted this as answer and included your suggestion for SortedDictionary with a heads up for the OP.

1 solution

A simple answer would be, list the shapes with their area, and then sort them in descending order based on their area, finally get the top 5.

Also, like Bill had mentioned in the comment, you can ignore the Dictionary, and use SortedDictionary[^]. That will sort the data automatically for you and you read them one by one. Please read this link to understand how this works. One heads however, if you will sort the data on the key, you might store only one shape for each weight.
 
Share this answer
 
Comments
BillWoodruff 25-Sep-19 13:55pm    
+5 I see your point: SortedDictionary cannot have duplicate keys ! I think he could use a SortedSet with a custom IComparer: https://stackoverflow.com/questions/5716423/c-sharp-sortable-collection-which-allows-duplicate-keys/34523348 ... but, probably just as efficient to write simpler code that just uses Linq Sort.
Afzaal Ahmad Zeeshan 25-Sep-19 13:56pm    
Thank you, Bill! :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900