Ask Your Question
0

Detect rectangles in image, crop and save in internal storage

asked 2018-09-02 06:57:58 -0600

50200 gravatar image

updated 2018-09-03 02:49:53 -0600

Hi i am working on a small Android project using Java where one of the so many functions is to detect rectangular (contains data) and crop the images into several different images (depend on the rectangular the image contains.) then store the images on internal storage (for other process).

I am very new at openCV. i have not done any openCV project. Is there anyone who can help me to guide how i can achieve this? i found some helps but all of them are in python which i have very less knowledge. Thanks in advance.

i need to crop all the rectangles with the number and dots

can anyone please provide some guidance to do so.. ?

This is what i did so far--

  public class ProcessesdResult extends AppCompatActivity {

   TextView tvProcessedText;
   Bitmap image;
   String photoPath;
   Mat imageMat;
   ImageView ProcessedImage;


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       OpenCVLoader.initDebug();

       setContentView(R.layout.activity_processesd_result);

       Intent intenttakeattendance = getIntent();
       String fname = intenttakeattendance.getStringExtra("fname");

       String root = Environment.getExternalStorageDirectory().toString();
       File myDir = new File(root);

       photoPath = myDir+"/sams_images/"+ fname;
       BitmapFactory.Options options = new BitmapFactory.Options();
       options.inPreferredConfig = Bitmap.Config.ARGB_8888;
       image = BitmapFactory.decodeFile(photoPath, options);

       ProcessedImage = findViewById(R.id.processedimage);

       // tvProcessedText = findViewById(R.id.tvprocessedtext);
       //imageProcess(image);
       imageCrop(image);
   }


   public void imageCrop(Bitmap bitmap){

       imageMat=new Mat();

       Utils.bitmapToMat(bitmap,imageMat);
       Mat imgSource=imageMat.clone();

       Mat imageHSV = new Mat(imgSource.size(), CvType.CV_8UC4);
       Mat imageBlurr = new Mat(imgSource.size(),CvType.CV_8UC4);
       Mat imageA = new Mat(imgSource.size(), CvType.CV_32F);
       Imgproc.cvtColor(imgSource, imageHSV, Imgproc.COLOR_BGR2GRAY);
       Imgproc.GaussianBlur(imageHSV, imageBlurr, new Size(5,5), 0);
       Imgproc.adaptiveThreshold(imageBlurr, imageA, 255,Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY,7, 5);

       List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
       Imgproc.findContours(imageA, contours, new Mat(), Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_SIMPLE);

       Vector<Mat> rectangles = new Vector<Mat>();

       for(int i=0; i< contours.size();i++){
           if (Imgproc.contourArea(contours.get(i)) > 50 )
             {
               Rect rect = Imgproc.boundingRect(contours.get(i));
               if ((rect.height > 30 && rect.height < 120) && (rect.width > 120 && rect.width < 500))
                 {
                    Rect rec = new Rect(rect.x, rect.y, rect.width, rect.height);
                    rectangles.add(new Mat(imgSource, rec));
                    Imgproc.rectangle(imgSource, new Point(rect.x,rect.y), new Point(rect.x+rect.width,rect.y+rect.height),new Scalar(0,0,255));
                 }
            }
       }

       Bitmap analyzed=Bitmap.createBitmap(imgSource.cols(),imgSource.rows(),Bitmap.Config.ARGB_8888);
       Utils.matToBitmap(imgSource,analyzed);

       saveTempImage(analyzed);
       ProcessedImage.setImageBitmap(analyzed);

   }


/*------------------------------------ Store Image -------------------------------------------*/
   public void saveTempImage(Bitmap bitmap) {
        if (isExternalStorageWritable()) {
            saveImage(bitmap);
        }else{
               Toast.makeText(this, "Please provide permission to write on the Storage!", Toast.LENGTH_SHORT).show();
        }
    }

    private void saveImage(Bitmap finalBitmap) {

        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/sams_images");

        if (! myDir.exists()){
            myDir.mkdir();
           // If you require it to make the entire directory path including parents,
           // use directory.mkdirs(); here instead.
       }

       String  timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date());
       String fname = timeStamp +".jpg";

       File file = new File(myDir, fname);
       if (file.exists()) file.delete ();
       try {
           FileOutputStream out = new FileOutputStream(file);
           finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
           out.flush();
           out.close();

       } catch (Exception e) {
           e.printStackTrace();
         }
   }

   /* Checks if external storage is available for read ...
(more)
edit retag flag offensive close merge delete

Comments

please take a look at the searchbar here.

this is a solved problem and has been answered multiple times.

berak gravatar imageberak ( 2018-09-02 07:07:35 -0600 )edit

thank you for the suggestion. i tried but did not found any solution that suits my problem. most of the solutions are for edge detection of a single image. the few i found either in Java or nor answered. anyway, i will keep looking with different keyword.

50200 gravatar image50200 ( 2018-09-02 07:22:29 -0600 )edit

you're basically asking us to 'write your app'. it won't happen.

berak gravatar imageberak ( 2018-09-02 11:18:29 -0600 )edit

sorry if my question seems that way, i just wanted the steps (algorithm) and even if it means just a list of statement.. that's why i mentioned in my question that i need "guidance" not necessarily codes.. hope you understand.. thank you for your reply anyway.

50200 gravatar image50200 ( 2018-09-02 11:30:54 -0600 )edit
1

Then can you write a code looking for contours and show us what is your problem?

LBerger gravatar imageLBerger ( 2018-09-03 02:36:53 -0600 )edit
1

@LBerger thank you a lot. I found the solution. but still there is a small problem. I edited the post.

50200 gravatar image50200 ( 2018-09-03 02:40:07 -0600 )edit
1

you can use copyTo in C++ but I think in java you can use this post

LBerger gravatar imageLBerger ( 2018-09-03 02:54:00 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2018-09-03 02:53:20 -0600

berak gravatar image

updated 2018-09-03 02:56:43 -0600

How to crop all the rectangles as bitmap and store those ?

you can use submat() like this:

if ((rect.height > 30 && rect.height < 120) && (rect.width > 120 && rect.width < 500))
{
     Rect rec = new Rect(rect.x, rect.y, rect.width, rect.height);
     Mat roi = imageMat.submat(rec);
     String filename = Environment.getExternalStorageDirectory() + ??? + ".png";
     Imgcodecs.imwrite(filename, roi); // no need for bitmap conversion here.
}
edit flag offensive delete link more

Comments

1

maybe you can also replace the loading code with a simple

Mat imageMat = Imgcodecs.imread(filename);

berak gravatar imageberak ( 2018-09-03 02:59:43 -0600 )edit
1

and hopefully, using:

Imgproc.findContours(imageA, contours, new Mat(), Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_SIMPLE);

will get rid of the "inner" contours there.

berak gravatar imageberak ( 2018-09-03 03:08:23 -0600 )edit

Thank you a lot for your suggestion. I tried that as you suggested but then it did not detect any contour at all. is there any other way to get rid of inner contours? should i use RECT_TREE then check hierarchy?

50200 gravatar image50200 ( 2018-09-03 05:19:50 -0600 )edit
2

If you want Imgproc.RETR_EXTERNAL to work, invert your image, so background black and lines white. Else you will have a large contour simply around the image.

StevenPuttemans gravatar imageStevenPuttemans ( 2018-09-03 07:13:55 -0600 )edit
1

@StevenPuttemans Thank you. its working perfectly now. I am really new at this. I really appreciate all of you for this support..

50200 gravatar image50200 ( 2018-09-03 08:41:42 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-09-02 06:57:58 -0600

Seen: 6,921 times

Last updated: Sep 03 '18