extract flower buds in x-ray image

asked 2018-04-29 04:39:03 -0500

bennog gravatar image

updated 2018-04-29 05:05:31 -0500

I am trying to extract and count the number of buds in of a flower in an x-ray image. in the example images it is so obvious where the buds are and how many buds there are, but I can not get the buds separated enough for proper counting. It is no problem if I get some false hits on the stem, because we plan to feed the cropped buds into a NN for classification

original 8 bit image

cropped original

the result I get is

image description

The perfect result would be the below image, this is impossible i know, but it should be better than the above result

image description

You can tweak this image by changing the threshold but then for the other images the result gets far worse.

8 bit enhanged images

16 bit original detector images

used code to get to current result.

// read first sample image
cv::Mat img8 = cv::imread("img8/006-img8bit.tif", cv::IMREAD_UNCHANGED);

// do some blur to remove most of the noise
cv::Mat imBlur;
cv::blur(img8, imBlur, cv::Size(5, 5));

// do close on grey image
cv::Mat imClose;
cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(15, 15));
cv::morphologyEx(imBlur, imClose, cv::MORPH_CLOSE, element);

// threshold image met auto threshold t.o.v. achtergrond kleur.
cv::Mat imgThresh;
//cv::adaptiveThreshold(imClose, imgThresh, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 71, 15.0);
cv::threshold(imClose, imgThresh, 29, 255, cv::THRESH_BINARY);  // automatic thresholding

// fillup small holes in threshold image
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));
cv::Mat imThClosed;
cv::morphologyEx(imgThresh, imThClosed, cv::MORPH_CLOSE, element, cv::Point(-1, -1), 2);

// try to remove most stems from image
cv::Mat imgThClean;
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(23, 23));
//cv::erode(imThClosed, imgThClean, element);
cv::morphologyEx(imThClosed, imgThClean, cv::MORPH_OPEN, element, cv::Point(-1, -1), 2);

// make contours
std::vector<std::vector<cv::Point> > contours;
cv::findContours(imgThClean.clone(), contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

// draw the contours
cv::drawContours(img8, contours, -1, cv::Scalar(255));
edit retag flag offensive close merge delete


could you add a single (8 bit) image here ? (maybe as a png, or such)

(it's somewhat unlikely, that folks will download a whole x mb archive of it)

berak gravatar imageberak ( 2018-04-29 04:46:19 -0500 )edit

Also changed the .tiff to .png so they are visible in the question.

bennog gravatar imagebennog ( 2018-04-29 05:03:59 -0500 )edit