软件开发说明
1. 基于OpenCV库,对含有细胞的图像进行处理。
2. 统计图像中所含细胞数量。
3. 输出最大和最小细胞的面积,周长(以像素为单位),方向,和该细胞的中心位置。
4. 输出所有细胞的平均面积。
5. 主要的中间步骤处理结果以cvShowImage的形式输出。
算法具体步骤
1. 图像的读入和转化
读入图像后转化为灰度图像
// Load image to src and Show source image Mat source = imread("cell1.bmp", CV_LOAD_IMAGE_COLOR); imshow("Source image", source);
// Get gray graph of source image. Mat gray; cvtColor(source, gray, CV_RGB2GRAY); imshow("Gray image", gray); |
2. 分离细胞与背景,并将图像二值化
int thresholdn = Otsu(gray); Mat bin; threshold(gray, bin, thresholdn, 255, CV_THRESH_BINARY); |
在分离细胞与背景图像的时候,最重要的是要找到一个合适的阈值,来进行图像和背景的二值化分离。这里我阅读了一些参考文献,决定采用otsu算法即最大类间方差法,又称大津算法。它是按图像的灰度特性,将图像分成背景和目标2部分。背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。
3. 获取细胞外围轮廓,及其面积、周长等。
这里我们使用findContours()函数来实现对细胞轮廓的获取,在此基础上舍弃一些轮廓,留下最终我们需要的,由于图像中有些和细胞颜色接近而面积远小于细胞的杂质,因此我们还需要对面积进行判断并且舍弃部分杂质。
vector<vector<Point>> contours; vector<Vec4i> hierarchy; Mat cont = Mat::zeros(bin.size(), CV_8UC1); Mat ellp = Mat::zeros(bin.size(), CV_8UC1); findContours(bin, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); |
|
计算平均面积:
for (int i = 0; i < contours.size(); i++){ if (hash[i]){ area[i] = contourArea(contours[i]); totalarea += area[i]; } }
int average = totalarea / counter; |