为啥openCV中的输入图像findContours()要转灰度?

Posted

技术标签:

【中文标题】为啥openCV中的输入图像findContours()要转灰度?【英文标题】:Why is the input image findContours() in openCV has to be converted to grayscale?为什么openCV中的输入图像findContours()要转灰度? 【发布时间】:2017-10-12 02:45:17 【问题描述】:

我正在关注以下网站上的教程:

http://harismoonamkunnu.blogspot.co.uk/2013/06/opencv-find-biggest-contour-using-c.html

如果我遵循代码,它会完美运行。但是,我所做的是输入灰度图像(由 photoshop 灰度并保存为 jpg),然后尝试跳过该步骤:

cvtColor(src,thr,CV_BGR2GRAY); //Convert to gray

当我再次在 Visual Studio 中运行相同的代码时,我收到一个运行时错误,显示:

image_capture.exe 中 0x00007FFE56A79E08 处未处理的异常: Microsoft C++ 异常:内存位置的 cv::Exception 0x000000C1D58FE1F0。发生了

在 countours.cpp 文件中:

scanner = cvStartFindContours( img, storage, cntHeaderSize, mode, method, offset );

我想尽量避免使用 cvtColor,因为在我的应用程序中,我的输入图像是灰度图片。我的代码如下:

#include "stdafx.h"
#include <iostream>
#include "opencv2\highgui\highgui.hpp"
#include "opencv\cv.h"
#include "opencv2\imgproc\imgproc.hpp"

using namespace cv;
using namespace std;
int main()

 int largest_area=0;
 int largest_contour_index=0;
 Rect bounding_rect;

 Mat src = imread("src.jpg"); //Load source image
 Mat thr(src.rows,src.cols,CV_8UC1); 
 Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0));
 //cvtColor(src,thr,CV_BGR2GRAY); //Convert to gray
 threshold(src, src,25, 255,THRESH_BINARY); //Threshold the gray

    vector<vector<Point>> contours; // Vector for storing contour
    vector<Vec4i> hierarchy;

    findContours( src, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image

     for( int i = 0; i< contours.size(); i++ ) // iterate through each contour. 
      
       double a=contourArea( contours[i],false);  //  Find the area of contour
       if(a>largest_area)
       largest_area=a;
       largest_contour_index=i;                //Store the index of largest contour
       bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
       

      

 Scalar color( 255,255,255);
 drawContours( dst, contours,largest_contour_index, color, CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
 rectangle(src, bounding_rect,  Scalar(0,255,0),1, 8,0);  
 imshow( "src", src );
 imshow( "largest Contour", dst );
 waitKey(0);

知道如何避免 cvtColor() 吗?

谢谢

【问题讨论】:

问题是您的图像的像素值可能是灰度的,但图像本身有多个通道,很可能是 3 个通道。 findContour 函数只接受 1 通道图像。 docs.opencv.org/3.3.0/d3/dc0/… 只要确保你的图像只有一个通道,可以很容易地用img.shape验证,如果它有超过1个通道,那么你可以切片多通道矩阵来抓取任何一个代表您的输入灰度图像的组成通道。 Mat src = imread("src.jpg", cv::IMREAD_GRAYSCALE); @ZdaR 我是 openCV 的新手。您能否就如何做到这一点提供一些指导?我只能找到 reshape() 方法。 【参考方案1】:

根据opencv documentation,findContour 函数的输入图像必须是 8 位单通道,因此您必须将输入图像更改为 thresholdcvtColor 等类型。如果您的图像是灰度图像,只需在CV_LOAD_IMAGE_GRAYSCALE 模式下加载即可。

cv::Mat rawImg = imread(imgName, CV_LOAD_IMAGE_GRAYSCALE);

【讨论】:

以上是关于为啥openCV中的输入图像findContours()要转灰度?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 cv2.findContours 结果中重新创建带有孔的原始图像?

Python-OpenCV中的图像轮廓检测

OpenCV计算机图像处理 —— 凸性缺陷 + 点多边形测试 + 形状匹配 + 轮廓分层与cv.findContours()

youcans 的 OpenCV 例程200篇194.寻找图像轮廓(cv.findContours)

youcans 的 OpenCV 例程200篇194.寻找图像轮廓(cv.findContours)

OpenCV findContours 堆栈溢出