OpenCV Functions of C++ I/F (cv::xxx)
Ejemplo n.º 1
0
        public static int ExtractTables(Image img)
        {
            //Delete this after
            Bitmap bit;


            List <Rectangle> AreasOfInterest = new List <Rectangle>();
            Bitmap           bitmap          = (Bitmap)img;

            Mat srcImg = OCS.Extensions.BitmapConverter.ToMat(bitmap);

            if (srcImg.Data == null)
            {
                throw new NullReferenceException("Image has nothing?");
            }

            //Resize into smaller size
            Mat rsz = new Mat();

            OpenCvSharp.Size size = new OpenCvSharp.Size(4000, 2828);
            Cv2.Resize(srcImg, rsz, size);

            // Convert to greyscale if it has more than one channel
            // else just leave it alone
            Mat grey = new Mat();

            Cv2.CvtColor(rsz, grey, ColorConversionCodes.BGR2GRAY);

#if IMG_DEBUG
            Cv2.ImShow("grey", grey);
            Cv2.WaitKey(0);
#endif

            //Apply adaptive thresholding to get negative
            Mat bw = new Mat();
            Cv2.AdaptiveThreshold(~grey, bw, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 15, -2);
            bit = OCS.Extensions.BitmapConverter.ToBitmap(bw);
            bit.Save("bw.tiff", System.Drawing.Imaging.ImageFormat.Tiff);

            // Create two new masks cloned from bw.

            Mat horizontal = bw.Clone();
            Mat vertical   = bw.Clone();

            // adjust this for number of lines
            int scale = 10;

            /////////////////////////
            /////////////////////////
            /////////////////////////

            // Specify size on horizontal axis
            int horizontalsize = horizontal.Cols / scale;

            // Create structure element for extracting horizontal lines through morphology operations
            //Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize, 1));
            Mat horizontalStructure = Cv2.GetStructuringElement(MorphShapes.Rect, new OCS.Size(horizontalsize, 1));

            // Apply morphology operations
            //erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
            Cv2.Erode(horizontal, horizontal, horizontalStructure, new OCS.Point(-1, -1));
            //dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
            Cv2.Dilate(horizontal, horizontal, horizontalStructure, new OCS.Point(-1, -1));

            //    dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1)); // expand horizontal lines

            // Show extracted horizontal lines
#if IMG_DEBUG
            Cv2.ImShow("horizontal", horizontal);
            Cv2.WaitKey(0);
#endif
            bit = OCS.Extensions.BitmapConverter.ToBitmap(horizontal);
            bit.Save("horizontal.tiff", System.Drawing.Imaging.ImageFormat.Tiff);

            // Specify size on vertical axis
            int verticalsize = vertical.Rows / scale;

            // Create structure element for extracting vertical lines through morphology operations
            //Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1, verticalsize));
            Mat verticalStructure = Cv2.GetStructuringElement(MorphShapes.Rect, new OCS.Size(1, verticalsize));

            // Apply morphology operations
            //erode(vertical, vertical, verticalStructure, Point(-1, -1));
            Cv2.Erode(vertical, vertical, verticalStructure, new OCS.Point(-1, -1));
            //dilate(vertical, vertical, verticalStructure, Point(-1, -1));
            Cv2.Dilate(vertical, vertical, verticalStructure, new OCS.Point(-1, -1));

            // Show extracted vertical lines
#if IMG_DEBUG
            Cv2.ImShow("vertical", vertical);
            Cv2.WaitKey(0);
#endif
            bit = OCS.Extensions.BitmapConverter.ToBitmap(vertical);
            bit.Save("vertical.tiff", System.Drawing.Imaging.ImageFormat.Tiff);


            // create a mask which includes the tables
            Mat mask = horizontal + vertical;
#if IMG_DEBUG
            Cv2.ImShow("mask", mask);
            Cv2.WaitKey(0);
#endif

            // find the joints between the lines of the tables, we will use this information in order to descriminate tables from pictures (tables will contain more than 4 joints while a picture only 4 (i.e. at the corners))
            Mat joints = new Mat();
            //bitwise_and(horizontal, vertical, joints);
            Cv2.BitwiseAnd(horizontal, vertical, joints);

            //Cv2.ImShow("joints", joints);
            bit = OCS.Extensions.BitmapConverter.ToBitmap(joints);
            bit.Save("joints.tiff", System.Drawing.Imaging.ImageFormat.Tiff);
#if IMG_DEBUG
            Cv2.ImShow("a", joints);
            Cv2.WaitKey(0);
#endif

            //Thread.Sleep(2000);


            // Find external contours from the mask, which most probably will belong to tables or to images
            //vector<Vec4i> hierarchy;
            //std::vector<std::vector<cv::Point>> contours;
            OCS.HierarchyIndex[] hierarchy;
            //List<List<OCS.Point>> contours = new List<List<OCS.Point>>;
            OCS.Point[][] contours;
            //cv::findContours(mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
            Cv2.FindContours(mask, out contours, out hierarchy, OCS.RetrievalModes.External, OCS.ContourApproximationModes.ApproxSimple, new OCS.Point(0, 0));

            //////vector<vector<Point>> contours_poly(contours.size() );
            //////vector<Rect> boundRect(contours.size() );
            //////vector<Mat> rois;
            List <List <OCS.Point> > contours_poly = new List <List <OCS.Point> >(contours.Length);
            List <OCS.Rect>          boundRect     = new List <OCS.Rect>(contours.Length);
            List <Mat> rois = new List <Mat>();


            ////for (size_t i = 0; i < contours.size(); i++)
            ////{
            ////    // find the area of each contour
            ////    double area = contourArea(contours[i]);
            ///
            ////    //        // filter individual lines of blobs that might exist and they do not represent a table
            ////    if (area < 100) // value is randomly chosen, you will need to find that by yourself with trial and error procedure
            ////        continue;
            ////    approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
            ////    boundRect[i] = boundingRect(Mat(contours_poly[i]));
            ////    // find the number of joints that each table has
            ////    Mat roi = joints(boundRect[i]);
            ////    vector<vector<Point>> joints_contours;
            ////    findContours(roi, joints_contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
            ////    // if the number is not more than 5 then most likely it not a table
            ////    if (joints_contours.size() <= 4)
            ////        continue;
            ////    rois.push_back(rsz(boundRect[i]).clone());
            ////    //drawContours( rsz, contours, i, Scalar(0, 0, 255), CV_FILLED, 8, vector<Vec4i>(), 0, Point() );
            ////    rectangle(rsz, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 1, 8, 0);
            ////}

            for (int i = 0; i < contours.Length; i++)
            {
                double area = Cv2.ContourArea(contours[i]);
                if (area < 100.0)
                {
                    // Skip because its not likely such a small area is a cell
                    continue;
                }
                // contours_poly is null at runtime. so we create a new entry and exit array
                contours_poly.Add(new List <OCS.Point>());
                OutputArray contour_poly_output = OutputArray.Create(contours_poly[i]);

                InputArray contour_poly_input = InputArray.Create(contours[i]);
                Cv2.ApproxPolyDP(InputArray.Create(contours[i]), contour_poly_output, 0.0, true);
                Rect boundingRect = Cv2.BoundingRect(InputArray.Create(contours_poly[i]));
                boundRect.Add(boundingRect);
                //boundRect[i] = Cv2.BoundingRect(InputArray.Create(contours_poly[i]));
                //OCS.Mat roi = Cv2.joints()
            }
#if IMG_DEBUG
            Cv2.NamedWindow("Output", WindowMode.KeepRatio);
            Cv2.Rectangle(rsz, boundRect.ElementAt(0), Scalar.Red, 10);
            Cv2.ImShow("Output", rsz);
            Cv2.WaitKey(0);
            Cv2.DestroyAllWindows();
#endif
            ////for (size_t i = 0; i < rois.size(); ++i)
            ////{
            ////    /* Now you can do whatever post process you want
            ////     * with the data within the rectangles/tables. */
            ////    imshow("roi", rois[i]);
            ////    waitKey();
            ////}

            return(boundRect.Count);
        }
        /// <summary>
        /// Computes an image descriptor using the set visual vocabulary.
        /// </summary>
        /// <param name="image">Image, for which the descriptor is computed.</param>
        /// <param name="keypoints">Keypoints detected in the input image.</param>
        /// <param name="imgDescriptor">Computed output image descriptor.</param>
        /// <param name="pointIdxsOfClusters">pointIdxsOfClusters Indices of keypoints that belong to the cluster.
        /// This means that pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster(word of vocabulary) returned if it is non-zero.</param>
        /// <param name="descriptors">Descriptors of the image keypoints that are returned if they are non-zero.</param>
        public void Compute(InputArray image, ref KeyPoint[] keypoints, OutputArray imgDescriptor,
                            out int[][] pointIdxsOfClusters, Mat descriptors = null)
        {
            ThrowIfDisposed();
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (imgDescriptor == null)
            {
                throw new ArgumentNullException(nameof(imgDescriptor));
            }

            using (var keypointsVec = new VectorOfKeyPoint(keypoints))
                using (var pointIdxsOfClustersVec = new VectorOfVectorInt())
                {
                    NativeMethods.features2d_BOWImgDescriptorExtractor_compute11(ptr, image.CvPtr, keypointsVec.CvPtr,
                                                                                 imgDescriptor.CvPtr, pointIdxsOfClustersVec.CvPtr, Cv2.ToPtr(descriptors));
                    keypoints           = keypointsVec.ToArray();
                    pointIdxsOfClusters = pointIdxsOfClustersVec.ToArray();
                }
            GC.KeepAlive(image);
            GC.KeepAlive(imgDescriptor);
            GC.KeepAlive(descriptors);
        }
Ejemplo n.º 3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="indexParams"></param>
 /// <param name="searchParams"></param>
 public FlannBasedMatcher(IndexParams indexParams = null, SearchParams searchParams = null)
 {
     ptr = NativeMethods.features2d_FlannBasedMatcher_new(
         Cv2.ToPtr(indexParams), Cv2.ToPtr(searchParams));
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Detect keypoints in an image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="mask">Mask specifying where to look for keypoints (optional).
        /// Must be a char matrix with non-zero values in the region of interest.</param>
        /// <returns>The detected keypoints.</returns>
        public KeyPoint[] Detect(Mat image, Mat?mask = null)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            ThrowIfDisposed();

            image.ThrowIfDisposed();
            try
            {
                using var keyPoints = new VectorOfKeyPoint();
                NativeMethods.HandleException(
                    NativeMethods.features2d_Feature2D_detect_Mat1(ptr, image.CvPtr, keyPoints.CvPtr, Cv2.ToPtr(mask)));
                return(keyPoints.ToArray());
            }
            finally
            {
                GC.KeepAlive(this);
                GC.KeepAlive(image);
                GC.KeepAlive(mask);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// ウィンドウのプロパティを設定する
        /// </summary>
        /// <param name="propId">プロパティの種類</param>
        /// <param name="propValue">プロパティに設定する値</param>
#else
        /// <summary>
        /// Set Property of the window
        /// </summary>
        /// <param name="propId">Property identifier</param>
        /// <param name="propValue">New value of the specified property</param>
#endif
        public void SetProperty(WindowProperty propId, double propValue)
        {
            Cv2.SetWindowProperty(name, propId, propValue);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// ウィンドウのプロパティを取得する
        /// </summary>
        /// <param name="propId">プロパティの種類</param>
        /// <returns>プロパティの値</returns>
#else
        /// <summary>
        /// Get Property of the window
        /// </summary>
        /// <param name="propId">Property identifier</param>
        /// <returns>Value of the specified property</returns>
#endif
        public double GetProperty(WindowProperty propId)
        {
            return(Cv2.GetWindowProperty(name, propId));
        }