Following is an image of a blue colored blob detected in an Android app using OpenCV4Android. I used Core.inRange()
and Imgproc.findContours()
methods to find the contours, and Imgproc.drawContours()
to draw em.
Mat mask = new Mat();
Core.inRange(rgbaMat, lowerThreshold, upperThreshold, mask);
...
contours = new ArrayList<>();
Imgproc.findContours(dilatedMat, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
...
for ( int contourIdx=0; contourIdx < contours.size(); contourIdx++ ) {
Imgproc.drawContours ( rgbaMat, contours, contourIdx, new Scalar(0, 255, 0), 1);
}
The contour (light green boundary) is outside the detected shape.
So, as you can see, it also includes some white area around the detected blue blob. I want the contour boundary to be inside the edges of the blue blob/shape. How can I do that?
EDIT: @sturkmen
Original Image:
(These are my complete files:*
MainActivity.java:
public class MainActivity extends Activity implements CvCameraViewListener2 {
private static final String TAG = MainActivity.class.getSimpleName();
private static Mat rgbaFrame;
private static final int pickImageRequestCode = 99;
private Mat rgbaMat;
private Mat rgbaMatCopy;
private ArrayList<MatOfPoint> contours;
private ImageView imageView;
private CameraBridgeViewBase cameraBridgeViewBase;
private BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i(TAG, "OpenCV loaded successfully!");
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.enableView();
}
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
@Override
public void onCameraViewStarted(int width, int height) {
rgbaFrame = new Mat(height, width, CvType.CV_8UC4);
}
@Override
public void onCameraViewStopped() {
rgbaFrame.release();
}
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
rgbaFrame = inputFrame.rgba();
return rgbaFrame;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.mainActivity_imageView);
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, baseLoaderCallback);
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, pickImageRequestCode);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if (resultCode == Activity.RESULT_OK && requestCode == pickImageRequestCode) {
Uri selectedImageUri = imageReturnedIntent.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
rgbaMat = new Mat();
rgbaMatCopy = new Mat();
rgbaMat = Highgui.imread(filePath);
rgbaMatCopy = Highgui.imread(filePath);
Imgproc.cvtColor(rgbaMat, rgbaMat, Imgproc.COLOR_BGR2RGB);
Imgproc.cvtColor(rgbaMatCopy, rgbaMatCopy, Imgproc.COLOR_BGR2RGB);
Mat hsvMat = new Mat();
Imgproc.cvtColor(rgbaMatCopy, hsvMat, Imgproc.COLOR_RGB2HSV);
Scalar lowerThreshold = new Scalar(100, 146, 148);
Scalar upperThreshold = new Scalar(134, 255, 255);
Mat mask = new Mat();
Core.inRange(hsvMat, lowerThreshold, upperThreshold, mask);
Mat dilatedMask = new Mat();
Imgproc.dilate(mask, dilatedMask, new Mat());
Imgproc.dilate(dilatedMask, dilatedMask, new Mat());
contours = new ArrayList<>();
Imgproc.findContours(dilatedMask, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
Imgproc.drawContours(rgbaMatCopy, contours, contourIdx, new Scalar(0, 255, 0), 1);
}
Bitmap theBitmap = Bitmap.createBitmap(rgbaMatCopy.cols(), rgbaMatCopy.rows(),
Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rgbaMatCopy, theBitmap);
imageView.setImageBitmap(theBitmap);
}
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<ImageView
android:id="@+id/mainActivity_imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
</RelativeLayout>