Adaptive threshold , find outlines , floodfill ?
Basically, an adaptive threshold turns your image into black and white, but takes a threshold level depending on local conditions around each pixel. Therefore, you should avoid the problem that you are facing with a normal threshold. In fact, I'm not sure why anyone would want to use a normal threshold.
If this does not work, an alternative approach is to find the largest outline in the image, draw it on a separate matrix, and then fill everything inside it with black. (Floodfill is similar to the bucket tool in MSPaint — it starts with a specific pixel and fills everything connected with that pixel, which has the same color with a different color of your choice.)
Perhaps the most reliable approach to various lighting conditions is to do it all in the sequence above. But you can only leave with a threshold or with a counter / fill.
By the way, maybe the hardest part is finding the outlines, because findContours returns arraylist / vector / whatever (platform dependent, I think) from MatOfPoints. MatOfPoint is a subclass of Mat, but you cannot draw it directly - you need to use drawContours. Here is some code for OpenCV4Android that I know works:
private Mat drawLargestContour(Mat input) { List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours(input, contours, new Mat() , Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); double maxArea = 0; int index = -1; for (MatOfPoint contour : contours) {
source share