【OpenCV 基础知识 15】蛇形处理算法

函数 cvSnakeImage 更新 snake 是为了最小化 snake 的整个能量,其中能量是依赖于轮廓形状的内部能量(轮廓越光滑,内部能量越小)以及依赖于能量场的外部能量之和,外部能量通常在哪些局部能量极值点中达到最小值(这些局部能量极值点与图像梯度表示的图像边缘相对应)。
参数 criteria.epsilon 用来定义必须从迭代中除掉以保证迭代正常运行的点的最少数目。
如果在迭代中去掉的点数目小于 criteria.epsilon 或者函数达到了最大的迭代次数 criteria.max_iter ,则终止函数。

program cv_SnakeImage;

{$APPTYPE CONSOLE}
{$POINTERMATH ON}

uses
  System.SysUtils,
  ocv.highgui_c,
  ocv.core_c,
  ocv.core.types_c,
  ocv.imgproc_c,
  ocv.imgproc.types_c,
  ocv.legacy,
  uResourcePaths;

const
  w = 500;
  filename = cResourceMedia + 'cat2.jpg';

var
  imgA, imgB, imgAA: pIplImage;
  storage: pCvMemStorage;
  contour: pCvPointArray;
  Approx_contours: PcvSeq;
  contour_num: integer;
  i1, i2, i, j, length, f1: integer;
  point: pInteger;
  c_alpha: single = 0.45;
  c_beta: single = 0.10;
  c_gamma: single = 0.45;
  contours: pCvPoint;

begin
  try
    // 创建名为 'image' 的窗口,窗口属性为自动调整大小
    cvNamedWindow('image', 1);

    // 从文件加载图像并将其分配给变量 `imgA`
    imgA := cvLoadImage(filename, CV_LOAD_IMAGE_UNCHANGED);

    // 创建与 imgA 相同大小、深度和通道数的图像,将其分配给变量 `imgAA`
    imgAA := cvCreateImage(cvSize(imgA^.width, imgA^.height), imgA^.depth, imgA^.nChannels);

    // 复制图像 imgA 到 imgAA,也可以选择进行高斯平滑处理
    // cvSmooth(imgA, imgAA, CV_GAUSSIAN, 7, 0, 0);
    cvCopy(imgA, imgAA);

    // 创建与 imgA 相同大小的单通道灰度图像,将其分配给变量 `imgB`
    imgB := cvCreateImage(cvSize(imgA^.width, imgA^.height), IPL_DEPTH_8U, 1);

    // 将彩色图像 imgAA 转换为灰度图像 imgB
    cvCvtColor(imgAA, imgB, CV_BGR2GRAY);

    // 定义曲线的长度和分配内存空间
    length := 200;
    contour := AllocMem(sizeof(TCvPoint) * length);

    // 生成具有 length 个点的圆形轮廓
    for i := 0 to length - 1 do
    begin
      contour[i].x := round(200 * cos(2 * PI * i / length) + 100);
      contour[i].y := round(200 * sin(2 * PI * i / length) + 100);
    end;

    // 进入循环,执行蛇形图像处理
    while true do
    begin
      // 使用蛇形图像处理算法更新轮廓
      cvSnakeImage(imgB, contour, length, @c_alpha, @c_beta, @c_gamma, CV_VALUE, cvSize(21, 21),
        cvTermCriteria(CV_TERMCRIT_ITER, 1, 0.0), 1);

      // 复制 imgAA 到 imgA,并在图像上绘制蛇形轮廓
      cvCopy(imgAA, imgA);
      for i := 0 to length - 2 do
        cvLine(imgA, contour[i], contour[i + 1], CV_RGB(255, 0, 0), 2, 8, 0);
      cvLine(imgA, contour[length - 1], contour[0], CV_RGB(255, 0, 0), 2, 8, 0);

      // 在 'image' 窗口中显示图像
      cvShowImage('image', imgA);

      // 等待200毫秒,如果按下ESC键(ASCII码27),则退出循环
      if cvWaitKey(200) = 27 then
        Break;
    end;

    // 释放图像资源和关闭窗口
    cvReleaseImage(imgA);
    cvReleaseImage(imgB);
    cvDestroyAllWindows;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
  • 27
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D-Nolan

请我喝杯咖啡吧,鼓励一下创作!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值