Ask Your Question
0

Document Detection working with C++ code, But trouble in java conversion.

asked 2017-12-01 01:06:47 -0500

Ajay Gohel gravatar image

I developed an Document scanner. I am using opencv for image processing. It works perfectly with C++ code, but i want that in java so i converted it. But not detecting document properly when i am using java code.

Actually cant implement this line in java

sort(contours.begin(), contours.end(), compareContourAreas);

Result with c++ code Result With C++

Result wit Java code Result with Java

C++ code

using namespace cv;
using namespace std;

extern "C"
bool compareContourAreas(std::vector<cv::Point> contour1, 
std::vector<cv::Point> contour2) {
double i = fabs(contourArea(cv::Mat(contour1)));
double j = fabs(contourArea(cv::Mat(contour2)));
return (i > j);
}

extern "C"
JNIEXPORT jobject JNICALL
Java_com_example_setlmint_setlmint_CameraScreen_doWithMat(JNIEnv *env, jobject instance,
                                                      jlong matAddrGr, jlong matAddrRgba) {

Mat &image = *(Mat *) matAddrRgba;
Rect bounding_rect;

Mat thr(image.rows, image.cols, CV_8UC1);
cvtColor(image, thr, CV_BGR2GRAY); //Convert to gray
threshold(thr, thr, 150, 255, THRESH_BINARY + THRESH_OTSU); //Threshold the gray

vector<vector<Point> > contours; // Vector for storing contour
vector<Vec4i> hierarchy;
findContours(thr, contours, hierarchy, CV_RETR_CCOMP,
             CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image
sort(contours.begin(), contours.end(),
     compareContourAreas);            //Store the index of largest contour
bounding_rect = boundingRect((const _InputArray &) contours[0]);

rectangle(image, bounding_rect, Scalar(250, 250, 250) , 3);
jclass rectClass = env->FindClass("org/opencv/core/Rect");
jmethodID rectCtorID = env->GetMethodID(rectClass, "<init>", "(IIII)V");
return env->NewObject(rectClass, rectCtorID, bounding_rect.x, bounding_rect.y, bounding_rect.width, bounding_rect.height);

}

Converted into Java

 Rect bounding_rect;
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    mGray = inputFrame.gray();
    mRgbaT = mRgba.t();
    Core.flip(mRgba.t(), mRgbaT, 1);
    Imgproc.resize(mRgbaT, mRgbaT, mRgba.size());

      Imgproc.cvtColor( mRgba, mGray, Imgproc.COLOR_BGR2GRAY );
       Imgproc.threshold( mGray, mGray, 155, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU );

       List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
       Mat hierarchy = new Mat();
       Imgproc.findContours( mGray, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE );

    int index= 0 ;
    double maxim = 0;
    for (int contourIdx = 0; contourIdx<contours.size();contourIdx++){
        double temp;
        temp = contourArea( contours.get(contourIdx) );
        if (maxim<temp){
            maxim=temp;
            index=contourIdx;
        }
    }

       bounding_rect = Imgproc.boundingRect( contours.get( index ) );
       Imgproc.rectangle( mRgbaT, new Point( bounding_rect.x, bounding_rect.y ), new Point( bounding_rect.x + bounding_rect.height, bounding_rect.y + bounding_rect.width ), new Scalar( 250, 250, 250 ), 5 );

    return mRgbaT;
}

onCamera Function when using C++ code

 public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    mGray = inputFrame.gray();
    mRgbaT = mRgba.t();
    Core.flip(mRgba.t(), mRgbaT, 1);
    Imgproc.resize(mRgbaT, mRgbaT, mRgba.size());
    mBoundingRect = doWithMat(mGray.getNativeObjAddr(), mRgbaT.getNativeObjAddr());
   return mRgbaT;
}
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-12-01 03:10:08 -0500

3 remarks come into mind right away

  • It seems that there is an offset on your camera. Could you just calculate the difference between your detection in C++ and JAVA and add it as a hard constraint of always adding/removing the offset?
  • It also seems that you are mixing width and height with x and y axis. X should correspond to width.
  • Keep in mind that OpenCV in C++ uses upper left corner as origin with downwards pointing y axis. However it might be possible that Java on Android uses bottom left origin with upright y axis. That could be the exact reason of your problem.
edit flag offensive delete link more

Comments

I dont think so problem is with axis, can u check the for please. I think something is wrong there.

Ajay Gohel gravatar imageAjay Gohel ( 2017-12-01 04:27:13 -0500 )edit

Hmm indeed. You are taking the current Area and checking if it is smaller than the one stored. You should check if it is larger! Now you are taking the smallest one possible! But then again, how can the dimensions be correct ...

StevenPuttemans gravatar imageStevenPuttemans ( 2017-12-01 04:47:06 -0500 )edit

Please could share answer for this quetion i am also working on document scanning .it very help for me

Jayapriya gravatar imageJayapriya ( 2019-06-07 05:14:00 -0500 )edit

We will not supply complete solutions. You have to work on it and if you have issues, post a decent question yourself and ask for help.

StevenPuttemans gravatar imageStevenPuttemans ( 2019-06-26 04:33:21 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2017-12-01 01:06:47 -0500

Seen: 824 times

Last updated: Dec 01 '17