【问题标题】:How to remove black borders from a frame in OpenCV using C++?如何使用 C++ 从 OpenCV 中的框架中删除黑色边框?
【发布时间】:2016-04-27 13:56:29
【问题描述】:

我想知道如何使用 C++ 从 OpenCV 中的以下帧中删除黑色边框

Original Image

Result

任何帮助将不胜感激。

【问题讨论】:

  • 只是让您知道,任何尝试此操作的人,您的图像顶部都有一条浅灰色线,这在一定程度上会混淆自动方法。这是故意的吗?
  • 该帧是红外视频的一部分。灰线不是故意的。
  • 图片的大小和黑边是固定的吗?如果是,您可以使用ROI

标签: c++ image opencv crop


【解决方案1】:

要去除一些非黑噪声,我建议使用cv::threshold 和形态关闭。然后,您可以删除包含(例如)超过 5% 非黑色像素的行和列。

我尝试了以下代码,它适用于您的示例:

int main()
{
  const int threshVal = 20;
  const float borderThresh = 0.05f; // 5%

  cv::Mat img = cv::imread("img.jpg", cv::IMREAD_GRAYSCALE);
  cv::Mat thresholded;
  cv::threshold(img, thresholded, threshVal, 255, cv::THRESH_BINARY);
  cv::morphologyEx(thresholded, thresholded, cv::MORPH_CLOSE,
    cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)),
    cv::Point(-1, -1), 2, cv::BORDER_CONSTANT, cv::Scalar(0));

  cv::imshow("thresholded", thresholded);

  cv::Point tl, br;

  for (int row = 0; row < thresholded.rows; row++)
  {
    if (cv::countNonZero(thresholded.row(row)) > borderThresh * thresholded.cols)
    {
      tl.y = row;
      break;
    }
  }

  for (int col = 0; col < thresholded.cols; col++)
  {
    if (cv::countNonZero(thresholded.col(col)) > borderThresh * thresholded.rows)
    {
      tl.x = col;
      break;
    }
  }

  for (int row = thresholded.rows - 1; row >= 0; row--)
  {
    if (cv::countNonZero(thresholded.row(row)) > borderThresh * thresholded.cols)
    {
      br.y = row;
      break;
    }
  }

  for (int col = thresholded.cols - 1; col >= 0; col--)
  {
    if (cv::countNonZero(thresholded.col(col)) > borderThresh * thresholded.rows)
    {
      br.x = col;
      break;
    }
  }

  cv::Rect roi(tl, br);
  cv::Mat cropped = img(roi);

  cv::imwrite("cropped.jpg", cropped);

  return 0;
}

请注意,为了在所有样本上获得最佳结果,您可能需要调整一些参数:threshValborderThresh

您可能还想阅读有关thresholdingmorphology transformations 的优秀教程。

【讨论】:

    【解决方案2】:

    来自阿卡尔萨科夫的回答。他将裁剪掉输入图像的黑色部分。但是,它将以灰度写入这个裁剪的图像。如果您喜欢颜色,请尝试更改并添加这些线条。

    #include "opencv2/opencv.hpp"
    
    using namespace cv;
    
    // Read your input image
    Mat img = imread("img.jpg");
    // Prepare new grayscale image
    Mat input_img_gray;
    // Convert to img to Grayscale
    cvtColor (img, input_img_gray, CV_RGB2GRAY);
    Mat thresholded;
    // Threshold uses grayscale image
    threshold(input_img_gray, thresholded, threshVal, 255, cv::THRESH_BINARY);
    

    我建议勾选 akarsakov 的答案,因为它确实有效。这仅适用于希望输出彩色图像的任何人:)

    【讨论】:

      猜你喜欢
      • 2018-11-16
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多