# Cell detection improvement

I would create a small application which counts the number of cells of a honey comb. (I'll count the number of covered and uncovered cells based on theirs color in the next step ...)

Most on uncovered cells are found but the covered and those which contains honey are still missing.

I would really appreciate if someone could help me how to improve my current contour detection solution. Any ideas, suggestions are welcomed.

This the input image: C:\fakepath\IMG_20150825_133836.jpg

Here is my code:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

int main(int /*argc*/, char** /*argv*/)
{
Mat src; Mat src_gray; Mat canny_output;
int thresh = 30;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

cvtColor(src, src_gray, CV_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
Canny(src_gray, canny_output, thresh, thresh * 2, 3);
/// Find contours
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Draw contours
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
if (contourArea(contours[i]) > 100) {       //filter noise
drawContours(drawing, contours, i, Scalar(255, 255, 255), -1, 8, hierarchy, 0, Point());
}
}
namedWindow("Comb", CV_WINDOW_AUTOSIZE);
imshow("Comb", drawing);
waitKey(0);
return(0);
}


The current output is:

edit retag close merge delete

I would suggest to pass to HSV and filter the orange colour (threshold on 20-30 Hue) and see what you get ;)

( 2015-11-06 06:55:01 -0500 )edit

Sort by » oldest newest most voted

First of all, I agree with @pklab: you could make your life much easier if you used a solid background

Said that, I'd take an approach using HoughCircles, as the hexagonal cells can be easily approximated

Mat image = imread("honeycomb.jpg");
Mat gray; cvtColor(image, gray, CV_BGR2GRAY);

//Trying to remove non-uniform background
vector<Mat>bgr;
split(image, bgr);
Mat binary;
threshold(bgr[0], binary, 80, 255, CV_THRESH_BINARY_INV);   //thresholding blue component
Mat kernel = getStructuringElement(MORPH_RECT, Size(8, 8));
Mat kernel2 = getStructuringElement(MORPH_RECT, Size(50, 50));
morphologyEx(binary, binary, MORPH_OPEN, kernel);
morphologyEx(binary, binary, MORPH_CLOSE, kernel2);
Mat gray_filtered;

//Retrieving circles
vector<Vec3f> circles;
HoughCircles(gray_filtered, circles, CV_HOUGH_GRADIENT, 2, 10, 100, 20, 5, 10);
for (size_t i = 0; i < circles.size(); i++)
{
Point center = Point(round(circles[i][0]), round(circles[i][1]));
circle(image, center, 0, Scalar(255, 255, 255));        //draw center in white
circle(image, center, radius, Scalar(0, 0, 255), 1);    //draw circle outline in red
}
imshow("Cells", image);
waitKey();


As you can see, there are still some missing cells, but a lot less than in your results. Also, there are some false positives that you can filter by defining the comb region, or by color (if that is your next step)

more

1

Nice solution. I only find it hard to find correct parameters for the HoughCircle algorithm whenever I use it. How do you define them to match your needs?

( 2015-11-07 15:23:35 -0500 )edit
1

I find it hard too to be honest, I don't have a clear strategy to adjust them. In this case it was easier as all the circles are of approximately same size and are regularly spaced (distance between centers is almost constant), so that allows for some helpful restrictions (but once again, best params were found just by trying and testing... Though in this case, I guess it could be done automatically by for example finding one of the cells with findContours in the first step, and then using its size to set the HoughCircles params and look for all cells). I usually struggle when I need the function to run in a more general scenario.

( 2015-11-07 15:38:58 -0500 )edit

Nice to see that I am not the only one :D

( 2015-11-08 03:21:32 -0500 )edit
1

( 2015-11-09 02:26:10 -0500 )edit

Because of non tele-centric lens on your camera and perpendicular angle used to take the picture you can see trough holes just in the center of the image. This would be a problem if covered cells aren't in the middle.

If it's possible try to take some countermeasure in a way that all empty holes looks all blind or all open. In other words all open holes should look close to white or close to black. Filled holes will remains as they are.

• Increase distance between camera and honey comb so you can see trough all open holes. Looking at the image 1.5 times should be enough
• Use a light on the floor, (usually color opposite to the object), in this case blue or white neon would be fine.
• If you can't use light try to use clean white background like a white paper
• Or use a black/opaque background

As alternative you could take picture using small angle instead of perpendicular. In this case you can't see trough holes at all.

About HSV I'm not sure that filtering HUE would help because, in this image, a lot of information is held in Saturation and Brightness.

A solution to vision project isn't just Algorithms.

EDIT: While answering about non uniform illumination I tested my function with your image. Using right thickness I can get a nice background for you.

here is the code and below the images.

the result after non uniform illumination (minThickess=4):

this is the removed background:

more

( 2015-11-09 02:28:49 -0500 )edit

Official site

GitHub

Wiki

Documentation