opencv知识(定期复习用)

一.阈值操作

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取灰度图像
    cv::Mat src = cv::imread("image.png", cv::IMREAD_GRAYSCALE);

    // 检查图像是否成功加载
    if (src.empty()) {
        std::cerr << "Error: Could not load input image." << std::endl;
        return -1;
    }

    // 创建用于存储结果的图像
    cv::Mat dst_binary, dst_binary_inv, dst_trunc, dst_tozero, dst_tozero_inv;

    // 设置阈值和最大值
    double thresh = 127;
    double max_value = 255;

    // 应用不同的阈值类型
    cv::threshold(src, dst_binary, thresh, max_value, cv::THRESH_BINARY);
    cv::threshold(src, dst_binary_inv, thresh, max_value, cv::THRESH_BINARY_INV);
    cv::threshold(src, dst_trunc, thresh, max_value, cv::THRESH_TRUNC);
    cv::threshold(src, dst_tozero, thresh, max_value, cv::THRESH_TOZERO);
    cv::threshold(src, dst_tozero_inv, thresh, max_value, cv::THRESH_TOZERO_INV);

    // 显示结果
    cv::imshow("Original Image", src);
    cv::imshow("Binary Threshold", dst_binary);
    cv::imshow("Binary Inverse Threshold", dst_binary_inv);
    cv::imshow("Truncate Threshold", dst_trunc);
    cv::imshow("To Zero Threshold", dst_tozero);
    cv::imshow("To Zero Inverse Threshold", dst_tozero_inv);

    cv::waitKey(0);
    return 0;
}
  • 第一种

  • cv::THRESH_BINARY

    • 如果像素值大于阈值,则设置为最大值,否则设置为0。
    • 公式:dst(x, y) = max_value if src(x, y) > thresh else 0
    • 示例:cv::threshold(src, dst, thresh, max_value, cv::THRESH_BINARY);
  • cv::THRESH_BINARY_INV

    • 如果像素值大于阈值,则设置为0,否则设置为最大值。
    • 公式:dst(x, y) = 0 if src(x, y) > thresh else max_value
    • 示例:cv::threshold(src, dst, thresh, max_value, cv::THRESH_BINARY_INV);
  • cv::THRESH_TRUNC

    • 如果像素值大于阈值,则设置为阈值,否则保持原值。
    • 公式:dst(x, y) = thresh if src(x, y) > thresh else src(x, y)
    • 示例:cv::threshold(src, dst, thresh, max_value, cv::THRESH_TRUNC);
  • cv::THRESH_TOZERO

    • 如果像素值大于阈值,则保持原值,否则设置为0。
    • 公式:dst(x, y) = src(x, y) if src(x, y) > thresh else 0
    • 示例:cv::threshold(src, dst, thresh, max_value, cv::THRESH_TOZERO);
  • cv::THRESH_TOZERO_INV

    • 如果像素值大于阈值,则设置为0,否则保持原值。
    • 公式:dst(x, y) = 0 if src(x, y) > thresh else src(x, y)
    • 示例:cv::threshold(src, dst, thresh, max_value, cv::THRESH_TOZERO_INV);

第二种:copyTo

 mask1.copyTo(mask_updated, mask2 > 0);

只有 mask2中值大于 0 的位置,mask1的值才会被复制到 mask_updated 中,其它位置保持不变。

第三种

  mask.convertTo(lipid_mask, CV_8UC1, 85.0);

85.0:缩放因子,即将 mask中的每个值乘以 85。

第四种

 temp_mask.setTo(0, mask == 2);

字面意思 ,等于2的为0

二:计算最大面积

   std::vector<std::vector<cv::Point>> contours;
   std::vector<cv::Vec4i> hierarchy;
   cv::findContours(temp_mask, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

   // 按轮廓面积排序,找到最大的轮廓
   std::sort(contours.begin(), contours.end(), [](const std::vector<cv::Point>& a, const std::vector<cv::Point>& b) {
       return cv::contourArea(a, false) > cv::contourArea(b, false);
       });
  • std::sort(contours.begin(), contours.end(), ...)

    • std::sort 是 C++ 标准库中的一个函数,用于对范围 [contours.begin(), contours.end()) 内的元素进行排序。
    • contours 是一个 std::vector<std::vector<cv::Point>> 类型的变量,其中每个元素是一个表示轮廓的点的向量。
  • [](const std::vector<cv::Point>& a, const std::vector<cv::Point>& b) { ... }

    • 这是一个 lambda 表达式,用作 std::sort 的比较函数。
    • Lambda 表达式捕获列表为空([]),表示不捕获任何外部变量。
    • 它接受两个参数 ab,这两个参数都是 const std::vector<cv::Point>& 类型的引用,表示两个要比较的轮廓。
  • cv::contourArea(a, false)cv::contourArea(b, false)

    • cv::contourArea 是 OpenCV 函数,用于计算轮廓的面积。
    • ab 是两个轮廓。
    • false 参数表示不计算轮廓的面积,默认为计算封闭区域的面积。
  • return cv::contourArea(a, false) > cv::contourArea(b, false);

    • 比较 ab 的面积。
    • 如果 a 的面积大于 b 的面积,则返回 true,否则返回 false
    • 这意味着 std::sort 会根据面积从大到小的顺序对轮廓进行排序

三:生成随机颜色以及随机取点

       //  将这些点打乱顺序
       std::random_device rd;
       std::mt19937 g(rd());
       std::shuffle(all_points_temp.begin(), all_points_temp.end(), g);
       
       //随机取50个点作为跟踪参考
       if (all_points_temp.size() > 50) {
           all_points_temp.resize(50);
       }
   std::vector<cv::Scalar> m_colors;

   cv::RNG rng(12345); 
   for (int i = 0; i < 1000; ++i) {
       int r = rng.uniform(0, 256);
       int g = rng.uniform(0, 256);
       int b = rng.uniform(0, 256);
       m_colors.push_back(cv::Scalar(b, g, r));
   }

四:根据新点到旧点越来越粗画线

for (int i = feature_points.size() - 1; i > 0; --i) {
    if (feature_points.size() < 2) {
        continue;
    }

    bool p2Circle = (i + 1) >= feature_points.size();
    draw_bgr_img = drawLines(draw_bgr_img, feature_points[i], feature_points[i - 1], p2Circle, mask, colorDeep);
    colorDeep = std::pow(colorDeep, 1.8);
}

output_img = draw_bgr_img.clone();


cv::Mat maskLines = cv::Mat::zeros(bgr2.size(), bgr2.type());

  for (size_t i = 0; i < p2.size(); ++i) {
      cv::Point2f new_pt = p2[i];
      cv::Point2f old_pt = p1[i];
      cv::line(maskLines, new_pt, old_pt, m_colors[i] * colorDeep, 2);

      if (p2Circle) {
          cv::circle(maskLines, new_pt, 3, m_colors[i], -1);
      }
  }

  if (!mask.empty()) {
      maskLines.setTo(cv::Scalar(0, 0, 0), mask == 0);
  }

  cv::add(bgr2, maskLines, bgr2);

  return bgr2;

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值