医疗图像分割技术(一)-程序员宅基地

技术标签: 机器学习  计算机视觉  人工智能  

在这里插入图片描述

图像分割演进之路
深度学习下的图像分割

 最近正在看一本有关医疗图像处理技术的书籍,里面有一整个章节在讲解各种医疗图像分割技术,
 与我之前写的两篇文章相比,细分到了医疗领域,医疗图像与其他领域相比,虽万变不离其宗,
 但仍有独特之处,所以想针对医疗领域图像分割再写一个系列的文章,希望对从事医疗算法的同行有所帮助,
 本系列文章分为如下四部分:


       **医疗图像分割概述和基本理论**
       基于模糊聚类的医疗图像分割
       基于可形变模型的医疗图像分割
       基于神经网络的医疗图像分割  

本篇文章主要讲解医疗图像分割概述和基本理论

1概述

2基于阈值的分割

2.1全局阈值

2.2局部阈值

2.3图像预处理

3区域增长

4分水岭

5基于边缘的图像分割

6多谱图像分割

6.1多模态

6.2多时域

1概述:

图像分割就是从背景中分离出感兴趣区域,在医疗领域,图像分割可以用来描绘解剖结构和组织类别,例如器官分割,病灶分割等,还可以用于可视化和图像压缩,是图像处理中非常重要的一个领域。

图像分割基本上可以通过两种方式实现,一种是识别出感兴趣区域内所有的像素,另一种先识别出感兴趣区域的边界来进行分割,第一种方法主要依赖于像素的灰度值,但像素的其他属性,例如纹理等也会被应用于图像分割,基于边界的分割方法主要依赖于图像的梯度。

2基于阈值的分割:

   有多种基于阈值的图像分割技术,有一部分是基于图像直方图,例如,基于整幅图像的直方图选择一个阈值,
   这种方式叫做全局阈值分割;其他的则是基于图像局部属性,例如局部均值和方差,
   或者是局部梯度,这种方式叫做局部阈值分割。

2.1全局阈值:

全局阈值假设图像的直方图满足双峰形状:

图片

这样选取一个阈值就能将图像一分为二,例如,我们选取阈值T,则分割的结果为:

图片

下面是一个全局阈值分割的例子:

图片

除了根据直方图选取分割阈值外,还有许多计算分割阈值的方法,其中一个是基于能够让错分概率最小化的分类模型,下面这篇论文讲述基于该方法实现MR脑部分割:

MR quantification of cerebral ventricular volume using a semiautomated algorithm

他的缺点也很明显,它需要目标与背景有很好的对比度,如果对比度低,或者图像有噪声则效果不理想,现实中很少有图像直方图满足严格的双峰形状。

2.2局部阈值:

当全局阈值不适用时,可以考虑使用局部阈值,局部阈值可以通过如下步骤获得:

1.将整幅图像划分为多个小图像,然后分别计算每个小图像的阈值

2.最简单的可以将所有小图像阈值的均值作为整幅图像的分割阈值

2.3图像预处理:

如果图像对比度低,边界模糊,可以通过图像预处理技术来改善图像直方图,例如中值滤波,如下图所示,图像经中值滤波后直方图出现双峰形状,除了中值滤波还有其他方法,这里就不再一一赘述了。

图片

在Opencv中实现了基本的基于阈值的图像分割技术。

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>

using namespace cv;
using std::cout;

/// Global variables

int threshold_value = 0;
int threshold_type = 3;
int const max_value = 255;
int const max_type = 4;
int const max_binary_value = 255;

Mat src, src_gray, dst;
const char* window_name = "Threshold Demo";

const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted";
const char* trackbar_value = "Value";

//![Threshold_Demo]
/**
 * @function Threshold_Demo
 */
static void Threshold_Demo( int, void* )
{
   
    
    /* 0: Binary
     1: Binary Inverted
     2: Threshold Truncated
     3: Threshold to Zero
     4: Threshold to Zero Inverted
    */
    threshold( src_gray, dst, threshold_value, max_binary_value, cv::THRESH_TRIANGLE );
    imshow( window_name, dst );
}
//![Threshold_Demo]

/**
 * @function main
 */
int main( int argc, char** argv )
{
   
    
    //! [load]
    String imageName("D:\\basketball2.png"); // by default
    if (argc > 1)
    {
   
    
        imageName = argv[1];
    }
    src = imread( samples::findFile( imageName ), IMREAD_COLOR ); // Load an image

    if (src.empty())
    {
   
    
        cout << "Cannot read the image: " << imageName << std::endl;
        return -1;
    }

    cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to Gray
    //cvtColor( src, src_gray, COLOR_BGR2HSV); // Convert the image to Gray
    //! [load]

    //! [window]
    namedWindow( window_name, WINDOW_AUTOSIZE ); // Create a window to display results
    //! [window]

    //! [trackbar]
    createTrackbar( trackbar_type,
                    window_name, &threshold_type,
                    max_type, Threshold_Demo ); // Create a Trackbar to choose type of Threshold

    createTrackbar( trackbar_value,
                    window_name, &threshold_value,
                    max_value, Threshold_Demo ); // Create a Trackbar to choose Threshold value
    //! [trackbar]

    Threshold_Demo( 0, 0 ); // Call the function to initialize

    /// Wait until the user finishes the program
    waitKey();
    return 0;
}

3区域增长

区域增长也叫区域融合,就是寻找具有相同灰度值的像素组,需要手动或者自动设置一个种子点,然后不断地检查周边像素,如果周边像素与种子点相似,则将该像素吸纳进来,整个搜索过程不断地进行直到找不到相似像素为止,这个过程中相似性度量非常重要,可以对比像素点的灰度值,也可以对比以像素点为中心的一块区域内的均值。

图片

在opencv中已经实现了对区域增长的封装。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include <iostream>
#include "math.h"
 
using namespace cv;
using namespace std;
 
Point recent_Point, recent_Point1;
 
Mat RegionGrow(Mat src, Point2i pt, int th)
{
   
    
    Point2i ptGrowing;                        //待生长点位置
    int nGrowLable = 0;                                //标记是否生长过
    int nSrcValue = 0;                                //生长起点灰度值
    int nCurValue = 0;                                //当前生长点灰度值
    Mat matDst = Mat::zeros(src.size(), CV_8UC1);    //创建一个空白区域,填充为黑色
    //生长方向顺序数据
    int DIR[8][2] = {
   
     {
   
     -1, -1 }, {
   
     0, -1 }, {
   
     1, -1 }, {
   
     1, 0 }, {
   
     1, 1 }, {
   
     0, 1 }, {
   
     -1, 1 }, {
   
     -1, 0 } };
    vector<Point2i> vcGrowPt;                        //生长点栈
    vcGrowPt.push_back(pt);                            //将生长点压入栈中
    matDst.at<uchar>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41755306/article/details/127288758

智能推荐

小梅哥FPGA:ROM_SignalTap Ⅱ_如何将数字复制到.mif文件-程序员宅基地

文章浏览阅读424次。小梅哥FPGA:ROM_SignalTap Ⅱ目标:1.将实现一组固定的数据(三角波形表)存储在FPGA中,并使用IP核构建的片上ROM进行存储,开发板上电后,系统开始从ROM中读取数据,并将数据直接通过并口输出,通过使用SignalTap Ⅱ软件实时抓取并口上的数据,显示得到三角波形。2.使用Quartus Ⅱ软件中提供ISMCE工具在线更改ROM中的mif文件本章将学会的技能:1.如何调用ROM的IP核2.如何给mif文件写入数据,也就是给ROM写入数据3.如何使用FPGA的多余硬件来构造_如何将数字复制到.mif文件

ModuleNotFoundError: No module named ‘_ctypes‘的解决办法_modulenotfounderror: no module named '_ctypes-程序员宅基地

文章浏览阅读8.2k次,点赞7次,收藏12次。问题描述在linux上安装好python3.8.2后,要安装一个第三方依赖库,在安装此依赖库的时候报了ModuleNotFoundError: No module named '_ctypes'的error,导致安装失败,字面上理解就是缺少_ctypes这个module执行命令 yum install libffi-devel进行安装然后从"./configure …"重新安装python3.8.2所有前置依赖安装yum -y install zlib-devel bzip2-devel open_modulenotfounderror: no module named '_ctypes

PyQt5 界面展示图片问题(QtGui.QPixmap)-程序员宅基地

文章浏览阅读2.4w次,点赞18次,收藏97次。PyQt5问题总结之QPixmap界面展示图片有两种方式:1,通过图片的地址路径加载图片并显示example:from PyQt5.Qt import QtGui# 图片路径img_path="image_path.jpg"# 设置展示..._qtgui.qpixmap

mysql LAST_INSERT_ID() 为空值的原因_oceanbase插入id为空-程序员宅基地

文章浏览阅读690次。1.插入的id不为mysql自增主键,则无法查询到mysql官方文档中说道,LAST_INSERT_ID()会获取最后一个生成的AUTO_INCREMENT的值With no argument, LAST_INSERT_ID() returns a BIGINT UNSIGNED (64-bit) value representing the first automatically generated value successfully inserted for an AUTO_INCREMENT _oceanbase插入id为空

CTF-密码学相关_密钥eyo-程序员宅基地

文章浏览阅读5.8k次,点赞7次,收藏41次。参考:千千秀字、百度百科、CTF编码和加密总结、CTF常见编码和加密特征 、CTF中Crypty(密码类)入门必看目录字符编码1.ASCII编码2.Unicode编码3.UTF-8编码4.UTF-16编码5.进制转换6.URL字符编码7.摩斯电码8.Base64/32/16编码9.shellcode编码10.Quoted-printable编码..._密钥eyo

呦西震惊--datatables如何拿到关联对象中的值_data, type, row, meta 获取对象-程序员宅基地

文章浏览阅读266次。例如在json数据中user[{‘name’:‘zhangsan’,‘sex’:‘男’},class[{‘classname’:‘ruanjian’}]]要想拿到user关联的class的数据,先看看一下参考:function render( data, type, row, meta )描述:如果做为一个function,那么每当Datatables从columns中的cell获取数据时,都需要执行该方法。 注意,该方法会被多次调用,根据不同的数据类型,比如sorting(排序)、filter_data, type, row, meta 获取对象

随便推点

Opencv入门必读知识-程序员宅基地

文章浏览阅读1.6k次,点赞17次,收藏21次。鉴于同学们反映讲的有点快,这里我们做一个补充。OpenCV(Open Source Computer Vision)是一个开源的计算机视觉库,旨在提供计算机视觉和机器学习算法的实现。它是一个跨平台的库,可在多个操作系统上运行,包括Windows、Linux、macOS和Android。_opencv入门

最近很火的京东、天猫超市飞天茅台抢购是怎么回事,从原理流程给你们分析一波_京东90016-程序员宅基地

文章浏览阅读1.2w次,点赞15次,收藏59次。最近很火的京东、天猫超市飞天茅台抢购是怎么回事,从原理流程给你们分析一波文章目录京东茅台介绍天猫茅台介绍京东抢购流程简单明了的流程图null和90008服务器压力部分通俗易懂的锁其他原因天猫抢购流程简单明了的流程图令牌的方式抢购茅台为什么天猫的要公平一些最后本文数据都没有证据支撑,皆为作者遐想。如有雷同,均为巧合。京东茅台介绍最近茅台抢购突然就火了,莫名其妙。而最初的京东脚本抢购作者,留下一句,一个被京东警告截图,便销声匿迹。但是他掀起的波澜还在继续。那7k份在github上fork的代码,将生_京东90016

Spring Boot自动配置原理_springboot自动装配和自动配置-程序员宅基地

文章浏览阅读5.7k次,点赞4次,收藏4次。Spring Boot自动配置原理(源码分析)_springboot自动装配和自动配置

spark面试题总结-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏77次。spark面试基础篇_spark面试题

实验7-1-13 装箱问题 (20 分)_-20 装箱问题 分数 20 作者 ds课程组 单位 浙江大学 假设有n项物品,大小分别为s 1-程序员宅基地

文章浏览阅读242次。实验7-1-13 装箱问题 (20 分)假设有N项物品,大小分别为s ​1 ​​ 、s ​2 ​​ 、…、s ​i ​​ 、…、s ​N ​​ ,其中s ​i ​​ 为满足1≤s​i ​​ ≤100的整数。要把这些物品装入到容量为100的一批箱子(序号1-N)中。装箱方法是:对每项物品,顺序扫描箱子,把该物品放入足以能够容下它的第一个箱子中。请写一个程序模拟这种装箱过程,并输出每个物品所在的箱子序号,以及放置全部物品所需的箱子数目。输入格式: 输入第一行给出物品个数N(≤1000);第二行给出_-20 装箱问题 分数 20 作者 ds课程组 单位 浙江大学 假设有n项物品,大小分别为s 1

一些重要的C和C++开发框架和开源工具_用c和c++写的开源工具-程序员宅基地

文章浏览阅读2.9k次。1、值得学习的C语言开源项目1.1. WebbenchWebbench是一个在linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力。Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行。 下载链接:http://home.tiscali.cz/~cz2105_用c和c++写的开源工具

推荐文章

热门文章

相关标签