ZH ·
🌏 English

NumPy 到 OpenCV Mat 的转换技巧

Sigmoid 函数

Sigmoid 函数是一个具有特征性 "S" 型曲线(即 Sigmoid 曲线)的数学函数。

来自维基百科:Sigmoid_function

其公式为:S(t)=11+etS(t)=\frac {1}{1+e^{-t}}

我们可以使用 Python 和 NumPy 这样实现 Sigmoid 函数:

import numpy as np
z = 1/(1 + np.exp(-x))

现在,让我们用 C++ 在 OpenCV 中实现它。假设我们从神经网络获得了一个输出,作为名为 pred 的 [1, h, w] cv::Mat。然后我们执行类似 pred = sigmoid(pred) 的操作:

cv::Mat sigmoid(const cv::Mat& pred)
{
  cv::Mat z;
  cv::exp(-pred, z);
  z = 1.f/(1.f+z);
  return z;
}  

搞定,非常简单。😊

通道分离与合并

在 NumPy 或类似的 API 中,我们可以执行如下切片操作:

temp = preds[:2, :, :]

此操作将创建前两个通道的快照。在 OpenCV 中,我们可以通过通道分离(split)和合并(merge)来模拟这些操作:

  std::vector<cv::Mat> preds_split;
  cv::split(preds, preds_split);
  
  std::vector<cv::Mat> preds_temp = {preds_split[0], preds_split[1]};
  cv::Mat temp;
  cv::merge(preds_temp, temp);

NumPy 矩阵的条件过滤

假设我们有一个 NumPy 二维数组,其中第一个通道是输入图像的分数图(score map)。现在我们需要过滤出大于阈值的像素。

  pred_score = preds[0] # 提取 preds 输出的第一个通道
  pred_mask = pred_score > min_confidence 

在 C++ 中的实现如下:

  std::vector<cv::Mat> preds;
  cv::split(output, preds);
  cv::Mat pred_score = preds[0];

  cv::threshold(pred_score, pred_mask, min_confidence, 1.f, cv::THRESH_BINARY);
  cv::multiply(pred_mask, 255, pred_mask);
  pred_mask.convertTo(pred_mask, CV_8U);

未完待续