Ask Your Question
0

Auto Cropping after bitwise application

asked 2015-03-23 05:48:13 -0600

zms gravatar image

Hello, I had search around and found out this link to auto crop https://opencv-code.com/quick-tips/au...

but I had tried here from my image to crop only the color section but failed. Reading the code it looks like should be arbitrary select the background color but maybe I'm wrong. I'm attaching my image here, if anyone can give me a hint, I can try to test and do some coding hereimage description

appreciate on help

edit retag flag offensive close merge delete

Comments

@zms: Share your input image as well.

Spark gravatar imageSpark ( 2015-03-23 05:53:17 -0600 )edit

I had attached my input image in the previous question... the one with black background and the image I want to crop is orange...

zms gravatar imagezms ( 2015-03-23 05:56:51 -0600 )edit

background color seems to be the color in top left corner (image.at(0, 0)). You can debug the probgram to see exactly what is going different than what you have expected; or you can just threshold the image and get the needed region by applying boundingRect on the contour found on the binary image.

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-03-23 07:33:32 -0600 )edit

@thdrksdfthmn, do u mean res &= (color == im.at<cv::vec3b>(0,i)); is the coding to select the color which is based on the top left image?

zms gravatar imagezms ( 2015-03-26 02:40:55 -0600 )edit

No, this cv::Vec3b color = src.at<cv::Vec3b>(0,0); is setting the bg color as the tl corner

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-03-26 03:50:53 -0600 )edit

ok thank @thdrksdfthmn .. will check one by one..

zms gravatar imagezms ( 2015-03-26 23:57:25 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2015-06-01 03:32:58 -0600

here is my code adopted from squares.cpp. it finds appropriate quad areas and crop them.

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;

// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
static double angle( Point pt1, Point pt2, Point pt0 )
{
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}


// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
static void findSquares( const Mat& image, vector<vector<Point> >& squares , bool inv=false)
{
    squares.clear();

    Mat gray,gray0;

    vector<vector<Point> > contours;

    cvtColor(image,gray0,COLOR_BGR2GRAY);

    gray = gray0 >= 240;

    if (inv)
        gray = gray0 <= 10;

    // find contours and store them all as a list
    findContours(gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);

    vector<Point> approx;

    // test each contour
    for( size_t i = 0; i < contours.size(); i++ )
    {
        // approximate contour with accuracy proportional
        // to the contour perimeter
        approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);

        // square contours should have 4 vertices after approximation
        // relatively large area (to filter out noisy contours)
        // and be convex.
        // Note: absolute value of an area is used because
        // area may be positive or negative - in accordance with the
        // contour orientation
        if( approx.size() == 4 &&
                fabs(contourArea(Mat(approx))) > 500 &&
                isContourConvex(Mat(approx)) )
        {
            double maxCosine = 0;

            for( int j = 2; j < 5; j++ )
            {
                // find the maximum cosine of the angle between joint edges
                double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                maxCosine = MAX(maxCosine, cosine);
            }

            // if cosines of all angles are small
            // (all angles are ~90 degree) then write quandrange
            // vertices to resultant sequence
            if( maxCosine < 0.3 )
                squares.push_back(approx);
        }
    }
}

int main( int argc, char** argv )
{
    vector<vector<Point> > squares;

    Mat image = imread(argv[1], 1);
    if( image.empty() )
    {
        cout <<  "Could not open or find the image" << endl ;
        return -1;
    }


    findSquares(image, squares);

    if (squares.empty())
        findSquares(image, squares,true);

    if (squares.empty())
    {
        cout <<  "Could not find any result" << endl ;
        return -1;
    }

    // shows all the squares in the image
    for( size_t i = 0; i < squares.size()-1; i++ )
    {
        Rect r=boundingRect( Mat(squares[i]));
        Mat s= image(r);

        stringstream temp_stream;
        temp_stream << argv[1] << " - "<< i << ".jpg";


        imwrite(temp_stream.str(),s);
        imshow(temp_stream.str(),s);
    }
    waitKey(0);
    return 0;
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-03-23 05:48:13 -0600

Seen: 1,429 times

Last updated: Jun 01 '15