最近比较闲,跟同学聊天讲到他的课题:医学图像分割,提取左心室区域。
我就好奇要了原始图片,发现超声图像果然比红外图像分辨率低,他指给我左心室所在区域。
拿到这张图第一眼,脑海里蹦出无数个小想法:
查找opencv并没有现成的绘制扇形函数,只有手动绘制了。
大概思路为:
尝试参数后,代码如下:
//生成扇形轮廓,角度
void get_fans(Mat &img,cv::Point center,double angle, int radius)
{
ellipse(img, center, cv::Size(radius, radius), 0, 90 - angle / 2, 90 + angle / 2, Scalar(255, 255, 255), 3, 8);
//计算扇形顶点坐标,先计算弦长和高
int chord_len = radius*sin(angle*3.14 / (2 * 180));
int height = radius*cos(angle*3.14 / (2 * 180));
//一左一右,中心点加偏移量即为顶点坐标
cv::Point corner_1 = center + cv::Point(-chord_len, height);
cv::Point corner_2 = center + cv::Point(chord_len, height);
line(img, center, corner_1, Scalar(255, 255, 255), 3, 8);
line(img, center, corner_2, Scalar(255, 255, 255), 3, 8);
}
朋友只需要根据参数调整,就能得到他们项目所需要的掩模。这个程序只是生成一张扇形的轮廓,生成掩模,还需要提取轮廓重新绘制,并将内部填充。
这部分代码如下:
get_fans(maskImage, cv::Point(520, 0), 77.4, 806);
vector > contours;//查找轮廓
vector hierarchy;//轮廓需要
findContours(maskImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
maskImage = cv::Mat::zeros(cv::Size(srcImage.cols, srcImage.rows), CV_8UC1);
//绘制自定义掩模,CV_FILLED表示完全填充内部
drawContours(maskImage, contours, -1, cv::Scalar::all(255), CV_FILLED);
完整代码就不分享了,借用Kmeans在分类时存在需要不定时反色情形,在对视频序列处理时,直接阈值化后效果也不错。
Kmeans效果还是有那么点的: