简体   繁体   中英

How to remove black borders from a frame in OpenCV using C++?

I would like to know how to remove the black border from the following frame in OpenCV using C++

Original Image

Result

Any help would be really appreciated.

To remove some non-black noise I recommend using cv::threshold and morphology closing. Then you can just remove rows and columns which contains (for example) more than 5% non-black pixels.

I tried following code and it works for your example:

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;
}

Please note that in order to get the best results on all your samples you may need to adjust some parameters: threshVal and borderThresh .

Also you may want to read good tutorials about thresholding and morphology transformations .

From akarsakov's answer. His will crop out the black parts of the input image. But, it will write this cropped image in grayscale. If you are after colour try changing and adding these lines.

#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);

I'd recommend ticking akarsakov's answer because it definitely works. This is just for anyone looking to output a coloured image :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM