Matlab上3D数据的椭球拟合

2023-12-31

我正在研究一个3D体积 of CT肺部图像,为了检测结节,我需要为每个可疑结节拟合一个椭球模型,我该如何为此编写代码??? 结节是疑似肿瘤的物体,我的算法需要检查每个物体,并将其近似为椭球体,并根据椭球体参数计算8个特征来构建分类器,通过训练和测试来检测是否为结节数据,所以我需要拟合这样的椭球体

这里是体积的一部分CT 肺部图像

这是相同体积的另一片,但它包含一个结节(黄色圆圈有一个结节),所以我需要我的代码检查每个形状以确定它是否是结节


由于我们没有3D我开始使用的数据集2D.

因此,首先我们需要选择肺部,这样我们就不会计算内部的任何其他物体。由于这是灰度,我们首先需要以某种方式将其二值化。我用我自己的class picture for DIP这将大量使用我的growthfill所以我强烈建议先阅读以下内容:

  • 使用图像处理检测手部骨折 https://stackoverflow.com/a/37046721/2521214

您可以在其中找到所需的所有解释。现在对于你的任务我会:

  1. 将 RGBA 转为灰度<0,765>

    我只是计算强度i=R+G+B对于 24 位图像,通道为 8 位,结果可达3*255 = 765。由于输入图像是通过 JPEG 压缩的,因此图像中存在颜色失真和噪声,因此不要忘记这一点。

  2. 剪掉白色边框

    只需从边界每条外线的中间向中间投射光线(扫描线),并在遇到非白色像素时停止。我与700代替765来补偿图像中的噪声。现在您获得了可用图像的边界框,因此裁剪掉其余部分。

  3. 计算直方图

    为了补偿图像中的失真,请平滑直方图以消除所有不需要的噪声和间隙。然后从左到右找到局部最大值(red)。这将用于二值化阈值(它们之间的中间值)green)这是我的最终结果:

  4. 二值化图像

    只需根据直方图的**颗粒*强度对图像进行阈值处理即可。因此,如果i0,i1是直方图中左右两侧的局部最大强度,然后是阈值(i0+i1)/2。这是结果:

  5. 除去肺以外的所有东西

    这很容易,只需从外部填充黑色到一些预定义的背景颜色即可。然后以同样的方式将所有白色的东西与背景颜色相邻。这将去除人体表面、骨骼、器官和CT机只留下肺。现在用一些预定义的肺部颜色重新着色剩余的黑色。

    不应留下黑色,剩余的白色可能是结节。

  6. 处理所有剩余的白色像素

    因此,只需循环遍历图像,并在第一个白色像素命中时用预定义的结节颜色或不同的对象索引填充它以供以后使用。我还区分了表面(aqua)和内部(magenta)。这是结果:

    现在您可以计算每个结节的特征。如果您编写自定义代码floodfill为此,您可以直接从中获取以下内容:

    • 音量输入[pixels]
    • 表面积在[pixels]
    • 边界框
    • 位置(相对于肺)
    • 重心或质心

    这些都可以用作特征变量,也可以帮助拟合。

  7. 拟合找到的曲面点

    有很多方法可以实现这一点,但我会尽可能简化它以提高性能和准确性。例如,您可以使用质心作为椭球中心。然后找到min and max远离它的点并将它们用作半轴(+/-一些正交性校正)。然后就搜索这些初始值。欲了解更多信息,请参阅:

    • 近似搜索的工作原理 https://stackoverflow.com/a/36163847/2521214

    您将在链接中找到使用示例Q/As there.

[Notes]

所有项目符号都适用于3D。在构建自定义floodfill小心递归尾部。太多的信息会非常快溢出你的堆栈并且也会大大减慢速度。这是我如何使用一些自定义返回参数来处理它的小例子+growthfill I used:

//---------------------------------------------------------------------------
    void growfill(DWORD c0,DWORD c1,DWORD c2);                      // grow/flood fill c0 neigbouring c1 with c2
    void floodfill(int x,int y,DWORD c);                            // flood fill from (x,y) with color c
    DWORD _floodfill_c0,_floodfill_c1;                              // recursion filled color and fill color
    int   _floodfill_x0,_floodfill_x1,_floodfill_n;                 // recursion bounding box and filled pixel count
    int   _floodfill_y0,_floodfill_y1;
    void  _floodfill(int x,int y);                                  // recursion for floodfill
//---------------------------------------------------------------------------
void picture::growfill(DWORD c0,DWORD c1,DWORD c2)
    {
    int x,y,e;
    for (e=1;e;)
     for (e=0,y=1;y<ys-1;y++)
      for (   x=1;x<xs-1;x++)
       if (p[y][x].dd==c0)
        if ((p[y-1][x].dd==c1)
          ||(p[y+1][x].dd==c1)
          ||(p[y][x-1].dd==c1)
          ||(p[y][x+1].dd==c1)) { e=1; p[y][x].dd=c2; }
    }
//---------------------------------------------------------------------------
void picture::_floodfill(int x,int y)
    {
    if (p[y][x].dd!=_floodfill_c0) return;
    p[y][x].dd=_floodfill_c1;
    _floodfill_n++;
    if (_floodfill_x0>x) _floodfill_x0=x;
    if (_floodfill_y0>y) _floodfill_y0=y;
    if (_floodfill_x1<x) _floodfill_x1=x;
    if (_floodfill_y1<y) _floodfill_y1=y;
    if (x>   0) _floodfill(x-1,y);
    if (x<xs-1) _floodfill(x+1,y);
    if (y>   0) _floodfill(x,y-1);
    if (y<ys-1) _floodfill(x,y+1);
    }
void picture::floodfill(int x,int y,DWORD c)
    {
    if ((x<0)||(x>=xs)||(y<0)||(y>=ys)) return;
    _floodfill_c0=p[y][x].dd;
    _floodfill_c1=c;
    _floodfill_n=0;
    _floodfill_x0=x;
    _floodfill_y0=y;
    _floodfill_x1=x;
    _floodfill_y1=y;

    _floodfill(x,y);
    }
//---------------------------------------------------------------------------

和这里C++我用代码制作了示例图像:

picture pic0,pic1;
    // pic0 - source img
    // pic1 - output img
int x0,y0,x1,y1,x,y,i,hist[766];
color c;
// copy source image to output
pic1=pic0;
pic1.pixel_format(_pf_u);           // grayscale <0,765>
//                    0xAARRGGBB
const DWORD col_backg=0x00202020;   // gray
const DWORD col_lungs=0x00000040;   // blue
const DWORD col_out  =0x0000FFFF;   // aqua nodule surface
const DWORD col_in   =0x00800080;   // magenta nodule inside
const DWORD col_test =0x00008040;   // green-ish distinct color just for safe recoloring

// [remove white background]
// find white background area (by casting rays from middle of border into center of image till non white pixel hit)
for (x0=0        ,y=pic1.ys>>1;x0<pic1.xs;x0++) if (pic1.p[y][x0].dd<700) break;
for (x1=pic1.xs-1,y=pic1.ys>>1;x1>      0;x1--) if (pic1.p[y][x1].dd<700) break;
for (y0=0        ,x=pic1.xs>>1;y0<pic1.ys;y0++) if (pic1.p[y0][x].dd<700) break;
for (y1=pic1.ys-1,x=pic1.xs>>1;y1>      0;y1--) if (pic1.p[y1][x].dd<700) break;
// crop it away
pic1.bmp->Canvas->Draw(-x0,-y0,pic1.bmp);
pic1.resize(x1-x0+1,y1-y0+1);

// [prepare data]
// raw histogram
for (i=0;i<766;i++) hist[i]=0;
for (y=0;y<pic1.ys;y++)
 for (x=0;x<pic1.xs;x++)            
  hist[pic1.p[y][x].dd]++;
// smooth histogram a lot (remove noise and fill gaps due to compression and scanning nature of the image)
for (x=0;x<100;x++)
    {
    for (i=0;i<765;i++) hist[i]=(hist[i]+hist[i+1])>>1;
    for (i=765;i>0;i--) hist[i]=(hist[i]+hist[i-1])>>1;
    }
// find peaks in histogram (for tresholding)
for (x=0,x0=x,y0=hist[x];x<766;x++)
    {
    y=hist[x];
    if (y0<y) { x0=x; y0=y; }
    if (y<y0>>1) break;
    }
for (x=765,x1=x,y1=hist[x];x>=0;x--)
    {
    y=hist[x];
    if (y1<y) { x1=x; y1=y; }
    if (y<y1>>1) break;
    }
// binarize image (tresholding)
i=(x0+x1)>>1;                       // treshold with middle intensity between peeks
pic1.pf=_pf_rgba;                   // result will be RGBA
for (y=0;y<pic1.ys;y++)
 for (x=0;x<pic1.xs;x++)
  if (pic1.p[y][x].dd>=i) pic1.p[y][x].dd=0x00FFFFFF;
   else                   pic1.p[y][x].dd=0x00000000;
pic1.save("out0.png");
// recolor outer background
for (x=0;x<pic1.xs;x++) pic1.p[        0][x].dd=col_backg;  // render rectangle along outer border so the filling starts from there
for (x=0;x<pic1.xs;x++) pic1.p[pic1.ys-1][x].dd=col_backg;
for (y=0;y<pic1.ys;y++) pic1.p[y][        0].dd=col_backg;
for (y=0;y<pic1.ys;y++) pic1.p[y][pic1.xs-1].dd=col_backg;
pic1.growfill(0x00000000,col_backg,col_backg);              // fill its black content outside in
// recolor white human surface and CT machine
pic1.growfill(0x00FFFFFF,col_backg,col_backg);
// recolor Lungs dark matter
pic1.growfill(0x00000000,col_backg,col_lungs);              // outer border
pic1.growfill(0x00000000,col_lungs,col_lungs);              // fill its black content outside in
pic1.save("out1.png");
// find/recolor individual nodules
for (y=0;y<pic1.ys;y++)
 for (x=0;x<pic1.xs;x++)
  if (pic1.p[y][x].dd==0x00FFFFFF)
    {
    pic1.floodfill(x,y,col_test);
    pic1.growfill(col_lungs,col_test,col_out);
    pic1.floodfill(x,y,col_in);
    }
pic1.save("out2.png");

// render histogram
for (x=0;(x<766)&&(x>>1<pic1.xs);x++)
 for (y=0;(y<=hist[x]>>6)&&(y<pic1.ys);y++)
   pic1.p[pic1.ys-1-y][x>>1].dd=0x000040FF;
for (x=x0        ,y=0;(y<=100)&&(y<pic1.ys);y++) pic1.p[pic1.ys-1-y][x>>1].dd=0x00FF0000;
for (x=x1        ,y=0;(y<=100)&&(y<pic1.ys);y++) pic1.p[pic1.ys-1-y][x>>1].dd=0x00FF0000;
for (x=(x0+x1)>>1,y=0;(y<=100)&&(y<pic1.ys);y++) pic1.p[pic1.ys-1-y][x>>1].dd=0x0000FF00;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Matlab上3D数据的椭球拟合 的相关文章

  • Numpy 相当于 MATLAB 的 hist [重复]

    这个问题在这里已经有答案了 由于某种原因 Numpy 的 hist 总是返回比 MATLAB 的 hist 少 1 个 bin 例如在 MATLAB 中 x 1 2 2 2 1 4 4 2 3 3 3 3 Rep Val hist x un
  • Matlab的导入函数的范围是什么?

    我正在尝试将一些用 Matlab 编写的代码转换为独立的 编译的 Matlab 应用程序 然而 在出现一些奇怪的错误之后 我意识到代码大量使用了从路径中添加和删除的操作 以避免多次使用多个具有相同名称 但结果 计算不同 的函数这一事实 环顾
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之
  • 计算机视觉/道路跟踪入门

    我想开发一个可以跟踪和沿着道路行驶的系统 最初 我只想处理定义明确的道路 稍后可能会合并对定义不明确的道路的跟踪 我面临的问题是我不知道从哪里开始 我是图像处理领域的新手 我希望能得到一些关于从哪里开始以及应该阅读哪些关于该主题的书籍的指导
  • matlab中更快的插值方法

    我正在使用 interp1 来插值一些数据 temp 4 30 4 rand 365 10 depth 1 10 dz 0 5 define new depth interval bthD min depth dz max depth ne
  • 禁止 MATLAB 自动获取焦点[重复]

    这个问题在这里已经有答案了 我有以下问题 在我的 MATLAB 代码中 我使用如下语句 figure 1 更改某些数据的目标数字 问题是 在此 MATLAB 之后 系统将焦点集中在具有该图形的窗口上 当我在后台运行一个大脚本并尝试在计算机上
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看
  • 如何在 MATLAB 编译的应用程序中运行外部 .m 代码? [复制]

    这个问题在这里已经有答案了 我有一个 MATLAB 项目 我使用 MCC 对其进行编译以获得单个可执行文件 然后我想知道外部程序员是否可以在 exe 中执行他的一些 m 文件 而无需重新编译整个项目 重点是提供一个应用程序 其他开发人员可以
  • 照片马赛克算法。如何在给定基本图像和瓷砖列表的情况下创建马赛克照片?

    Hy 我要做的是创建一个程序 使用 C 或 C 它将 24 位 像素位图和图像集合作为输入 我必须创建一个马赛克图像 类似于使用库的输入图像给定的图像 创建与输入类似的马赛克照片 到目前为止 我可以访问输入的图像像素及其颜色 但我有点卡住了
  • 在 MATLAB 中绘图后恢复轴

    从文本文件绘制多种方法的输出后 未显示轴的右侧和上侧 我需要拥有它们并将它们加粗 就像当前的轴一样 绘制的数据来自存储每种方法数据的文件 每个数据文件都是一个 256x2 文件 包含 0 1 之间的值 第一列是精度 第二列是召回率 figu
  • MATLAB - 通过垂直连接子矩阵重新排列矩阵

    我在执行以下任务时遇到问题 假设一个 3x6 矩阵 A 0 2787 0 2948 0 4635 0 8388 0 0627 0 0435 0 6917 0 1185 0 3660 0 1867 0 2383 0 7577 0 6179 0
  • 如何选择面积最大的对象?

    我用过bwconvhull检测图像的某个部分 正如您在图像中看到的那样 有许多具有特定质心的对象 我想做的是检测面积最大的物体 左起第一个大物体 并忽略其他物体 我应该遵循哪种方法 我将非常感谢您的帮助 以下是代码 由于我仍在努力 所以写得
  • 使用简单矩阵乘法时出错

    我在一次简单的乘法运算中偶然发现了一个错误 这让我感到非常惊讶 我一直以为这里发生了什么 只为矩阵乘法 http www mathworks nl help matlab matlab prog operators html x 2 y z
  • Deploytool for MATLAB R2013b 不起作用,发生了什么变化?

    多年来我一直在使用集成deploytool为我的同事创建易于分发的 exe 文件 我几天前安装了R2013b 但无法使用deploytool不再了 尝试打包时的日志文件给出了以下内容 ant
  • matlab 中的动画绘图

    我正在尝试创建一个三角形的动画图 最终结果应该是十个三角形 后面跟着两个更大的三角形 后面跟着一条直线 使用matlab文档 https de mathworks com help matlab ref drawnow html 我最终得到
  • 安卓的限制

    我需要构建一个应用程序 该应用程序拍摄相机图像并将其上传到网络 在网络上进行一些处理并返回真 假 我在这方面遇到了一些问题 希望得到澄清 1 我的应用程序有什么方法可以知道 Android 相机捕获的图像吗 我从这里明白了什么 Androi
  • 轴标注问题

    通过运行我编写的以下 matlab 函数 可以互换图中的 x 轴和 y 轴 谁能告诉我问题出在哪里或者帮我解决它吗 预先感谢您的任何帮助 function axislabeling n x 1 1 n y 1 1 n z zeros n n
  • 如何从 matlab 调用 Qtproject?

    我在 matlab 中有一个函数可以写入一个 file txt 我在 qt 项目中使用它 So 当我使用 unix 获取要运行的 qt 编译可执行文件时 我有一个 Matlab 文件 但出现错误 代码 unix home matt Desk
  • 在矩阵中找到叉的最快方法

    定义 A i j 1 是十字的中点 如果元素A i 1 j 1A i 1 j 1A i j 1 1A i j 1 1 这些元素和中点一起形成矩阵 A 中的十字 其中 A 至少是一个 3 3 矩阵 并且i j 0 假设上图是 8 8 矩阵 A
  • 在骨架图像中查找线 OpenCV python

    我有以下图片 我想找到一些线来进行一些计算 平均长度等 我尝试使用HoughLinesP 但它找不到线 我能怎么做 这是我的代码 sk skeleton mask rows cols sk shape imgOut np zeros row

随机推荐