I am trying to detect a piece of paper from an image. Well I have had help from posts like this . But one difference is that my background color is almost same as the paper color, and I am getting wrong result.
[edit] By wrong result I mean the paper outline contour is not detected at all. instead the largest contour covers the whole image.
My code so far (using emgu cv and c#)
MemStorage storage = new MemStorage();
        List<Contour<Point>> candidateList = new List<Contour<Point>>();
        List<double> areaList = new List<double>();
        Image<Bgr, Byte> inputImage = new Image<Bgr, Byte>(image);
        //Rectangle roi = new Rectangle(15, 15, image.Width - 15, image.Height - 15);
        //inputImage.ROI = roi;
        //inputImage = inputImage.Copy();
        double threshHeight = inputImage.Size.Height * 0.50;
        double threshWidth = inputImage.Size.Width * 0.50;
        //std::vector<std::vector<cv::Point> > squares;
        //cv::Mat pyr, timg, gray0(_image.size(), CV_8U), gray;
        int thresh = 50, N = 5;
        //cv::pyrDown(_image, pyr, cv::Size(_image.cols/2, _image.rows/2));
        //cv::pyrUp(pyr, timg, _image.size());
        //std::vector<std::vector<cv::Point> > contours;
        Image<Gray, Byte> [] gray0 = new Image<Gray,byte>[3];
        for( int c = 0; c < 3; c++ ) {
            try{
                int [] ch = {c, 0};
                gray0[c] = new Image<Gray,byte>(inputImage.Size);
                CvInvoke.cvMixChannels(new IntPtr[] { inputImage }, 1, new IntPtr[]{gray0[c]}, 1, ch, 1);
                Image<Gray, Byte> gray = new Image<Gray,byte>(inputImage.Size);
                for (int l = 0 ; l < N ; l++){
                    if (l == 0){
                        Image<Gray, Byte> cannyImage = gray0[c].Canny(0, thresh, 5);
                        CvInvoke.cvDilate(cannyImage, gray, IntPtr.Zero, 1);
                        //CvInvoke.cvShowImage("ch " + c + "-" + l, gray);
                    }else{
                        CvInvoke.cvThreshold(gray0[c], gray, (l + 1)*255/N, 255, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY);
                        //CvInvoke.cvShowImage("ch " + c + "-" + l, gray0[c]);
                    }
                    //CvInvoke.cvShowImage("image", gray);    
                    for (Contour<Point> contours = gray.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext){
                        Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.02, storage);
                        if (currentContour.Count() >= 4){
                            if (currentContour.Area > 3000){
                            //if (currentContour.BoundingRectangle.Width >= threshWidth && currentContour.BoundingRectangle.Height > threshHeight){
                                candidateList.Add(currentContour);
                                areaList.Add(currentContour.Area);
                                inputImage.Draw(currentContour, new Bgr(255, 0, 0), 1);
                            }
                        }
                    }
                }
            }catch(Exception ex){
                Debug.WriteLine(ex.Message);
            }
        }
        /* finding the biggest one */
        double area = -1.0;
        Contour<Point> paper = null;
        for (int i = 0 ; i < candidateList.Count ; i++){
            if (areaList[i] > area){
                area = areaList[i];
                paper = candidateList[i];
            }
        }
        if (paper != null){
            if (paper.BoundingRectangle.Width >= threshWidth && paper.BoundingRectangle.Height > threshHeight){
                inputImage.Draw(paper, new Bgr(0, 0, 255), 2);
            }
        }
        return inputImage.ToBitmap();
Please let me know how to process these images.
 
     
    

