# OpenCV Java How can I find red lined Rectangles from 12 rectangles.

I am running into a very unique problem statement. I have an image which will have 12 led lights and a few out of them will glow as red. After trying out multiple algorithms, I have reached till this stage (See Image Below ) from an RGB image taken from the camera.

I have reached to this image by applying this algorithms -

Mat detectedEdges = new Mat(ImageMat.rows(), ImageMat.cols(), CvType.CV_8UC1);
//Imgproc.blur(ImageMatNew, detectedEdges, new Size(3,3));
Imgproc.GaussianBlur(ImageMatNew, detectedEdges, new Size(3,3), 7);
Imgproc.Canny(detectedEdges, detectedEdges, 70, 70 * 3, 3, false);
Imgproc.Canny(detectedEdges, detectedEdges, 10, 10 * 7, 7, true);


Now From here, I am completely lost. I have searched all over places and tried multiple approaches. So My problem state goes like this;

In this Image, there will be always 12 rectangles. Few rectangles will be red single lined eclosed and others will be black double lined eclosed rectangles. I have to find these single lined red enclosed rectangles and their number from top to bottom or bottom to top between 1-12.

I was trying with contours but I don't think contours are going to solve my any problem. Because I tried with Contour Area but here I can match the area or even can't approximate the area so that I can iterate from top to bottom.

I am stuck in this problem since a week. any slight hint or approach will help me Thanks in Advance.

edit retag close merge delete

Sort by » oldest newest most voted

I think the contour-based approach is not a good idea.

Try to segment the original image with the inRange function. For best results, first convert the image to the HSV color space.

Mat ImagHSV, segmented;
cvtColor(imageA,imageHSV,COLOR_BGR2HSV);
inRange(imageHSV,min,max,segmented)


Another idea would be to use a kind of excess red index by combining the RGB channels: ERI=2*R-G-B. Then threshold this image.

Mat channels[3],egi,segmented;
int threshold=50;    //set this according to your needs
split(imageA,channels);
egi=2*image[2]-image[1]-image[0];
segmented=egi>threshold;


The resulting image should contain only the red colored pixels (which are normally the LEDs). To get rid of the noise, use morphological operators (erosion).

Finally, to get the position of the LEDs, use the connected component analysis.

NOTE The code samples are for guidance only. They are untested and written in C++. You must understand these functions in order to use the algorithm correctly.

However implementing this algorithm in Java should be straightforward. Refer to the OpenCV documentation for further help and information about the rest of the functions (connected components, morphological operations).

more

@kbarni Thanks for your response. I know it could be very straightforward for an expert like you but I am very new to this. It will be very helpful if you can provide some code sample at least for two step 1. for InRange Step and 2. ERI Index. I tried to search this but could not find enough to implement.

Also as you said For best results, first convert the image to the HSV color space. Actually Above given attached image is processed Image (Say it ImageB) from my original Image (Say it ImageA), So are you saying that I should first convert ImageA to HSV color space or are you saying I should convert ImageB to HSV colorspace. and than I should follow step provided by you ?

( 2018-08-16 04:32:52 -0500 )edit

Work only with ImageA. The processing step taken to get ImageB is not the best approach.

I'll complete my previous answer with some code samples.

( 2018-08-16 11:42:59 -0500 )edit

thank you very much @kbarni for your response. It was very helpful. The only thing I couldn't find this segmented=egi>threshold; operation. did u mean this segmented=egi>>threshold; ? or something else ? because in C++ egi>threshold will return a boolean. I also didn't find anything related to this in java

( 2018-08-16 14:24:30 -0500 )edit

Yep. This is a matrix operation. It will return 0 or 1 (boolean true/false) for each pixel. See https://docs.opencv.org/2.4/modules/c...

You can also use the threshold function.

( 2018-08-16 16:15:28 -0500 )edit

thanks @kbarni I am trying this approach and will adjust the values. And will comment again if I stuck. Please dont mind :)

( 2018-08-17 13:35:15 -0500 )edit

Official site

GitHub

Wiki

Documentation