当前位置: 首页 > 知识库问答 >
问题:

OpenCV:如何检测特定颜色的线条?

孔阳平
2023-03-14

我正在做一个小的OpenCV项目,从手机摄像头中检测某种颜色的线条。

    null

这些是我想使用的函数,但不能安静地确定如何填补缺失的位。

这是在处理来自CvVideoCamera实例的图像时,从智能手机应用程序调用的processImage函数

- (void)processImage:(Mat&)image;
{
cv::Mat orig_image = image.clone();

cv::Mat red_image = ?? 

// Apply houghes transformation to detect lines between a minimum length and a maximum length (I was thinking of using the CV_HOUGH_PROBABILISTIC method..)
// Comment.. see below..

我无法理解这里的文档,因为C++方法签名没有方法字段

vector<Vec2f> lines;
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 ); 
for( size_t i = 0; i < lines.size(); i++ )
{
}

任何帮助都将不胜感激。

共有1个答案

景永望
2023-03-14

可以使用HSV颜色空间提取色调信息。

下面是一些带有注释的代码,如果有任何问题,请随意提问:

int main(int argc, char* argv[])
{
    cv::Mat input = cv::imread("C:/StackOverflow/Input/coloredLines.png");

    // convert to HSV color space
    cv::Mat hsvImage;
    cv::cvtColor(input, hsvImage, CV_BGR2HSV);

    // split the channels
    std::vector<cv::Mat> hsvChannels;
    cv::split(hsvImage, hsvChannels);

    // hue channels tells you the color tone, if saturation and value aren't too low.

    // red color is a special case, because the hue space is circular and red is exactly at the beginning/end of the circle.
    // in literature, hue space goes from 0 to 360 degrees, but OpenCV rescales the range to 0 up to 180, because 360 does not fit in a single byte. Alternatively there is another mode where 0..360 is rescaled to 0..255 but this isn't as common.
    int hueValue = 0; // red color
    int hueRange = 15; // how much difference from the desired color we want to include to the result If you increase this value, for example a red color would detect some orange values, too.

    int minSaturation = 50; // I'm not sure which value is good here...
    int minValue = 50; // not sure whether 50 is a good min value here...

    cv::Mat hueImage = hsvChannels[0]; // [hue, saturation, value]

    // is the color within the lower hue range?
    cv::Mat hueMask;
    cv::inRange(hueImage, hueValue - hueRange, hueValue + hueRange, hueMask);

    // if the desired color is near the border of the hue space, check the other side too:
    // TODO: this won't work if "hueValue + hueRange > 180" - maybe use two different if-cases instead... with int lowerHueValue = hueValue - 180
    if (hueValue - hueRange < 0 || hueValue + hueRange > 180)
    {
        cv::Mat hueMaskUpper;
        int upperHueValue = hueValue + 180; // in reality this would be + 360 instead
        cv::inRange(hueImage, upperHueValue - hueRange, upperHueValue + hueRange, hueMaskUpper);

        // add this mask to the other one
        hueMask = hueMask | hueMaskUpper;
    }

    // now we have to filter out all the pixels where saturation and value do not fit the limits:
    cv::Mat saturationMask = hsvChannels[1] > minSaturation;
    cv::Mat valueMask = hsvChannels[2] > minValue;

    hueMask = (hueMask & saturationMask) & valueMask;

    cv::imshow("desired color", hueMask);

    // now perform the line detection
    std::vector<cv::Vec4i> lines;
    cv::HoughLinesP(hueMask, lines, 1, CV_PI / 360, 50, 50, 10);

    // draw the result as big green lines:
    for (unsigned int i = 0; i < lines.size(); ++i)
    {
        cv::line(input, cv::Point(lines[i][0], lines[i][1]), cv::Point(lines[i][2], lines[i][3]), cv::Scalar(0, 255, 0), 5);
    }


    cv::imwrite("C:/StackOverflow/Output/coloredLines_mask.png", hueMask);
    cv::imwrite("C:/StackOverflow/Output/coloredLines_detection.png", input);

    cv::imshow("input", input);
    cv::waitKey(0);
    return 0;
}

使用此输入图像:

我不太确定所有的参数,也许你得看看关于hough线检测的文献,或者其他人可以在这里添加一些提示。

如果使用cv::houghlinesp,则会检测到具有起始点和结束点的线段,这更容易解释,并且可以从cv::norm(cv::point(lines[i][0],lines[i][1])-cv::point(lines[i][2],lines[i][3])计算行长

 类似资料:
  • 本文向大家介绍opencv 实现特定颜色线条提取与定位操作,包括了opencv 实现特定颜色线条提取与定位操作的使用技巧和注意事项,需要的朋友参考一下 本篇文章通过调用opencv里的函数简单的实现了对图像里特定颜色提取与定位,以此为基础,我们可以实现对特定颜色物体的前景分割与定位,或者特定颜色线条的提取与定位 主要步骤: 将RGB图像转化为HSV,H表示色调(度数表示0-180),S表示饱和度(

  • 问题内容: 我希望在Java中实现一项功能,该功能可以读取图像并能够检测红色,蓝色,绿色,黄色等阴影,作为卫星图像分析程序的一部分。因此,例如在标准卫星图像中,蓝色将是水,因此我希望程序读取多少像素是蓝色的,然后它可以说图像的x%是水。 我知道通过读取每个像素的RGB值可以使用整个逻辑语句负载,但是有没有更简单的方法呢?否则,将有数百个if语句,这些语句将花费很长时间来编写,但执行起来也会很长。理

  • 我正在Android上使用新的CameraX。 我做了一个基本的应用程序(类似于“入门”),其中我有一个相机预览和一个亮度分析器。每秒钟我都会在文本视图中显示我的LUMONITY。 现在,按照CameraX指南,我想做颜色检测。每隔一秒钟左右,我想让屏幕中央像素的颜色。 事实上,我不知道如何按照与光度分析器相同的结构进行颜色检测。 光度分析仪等级: 主要活动: 除了成为色彩分析仪,我如何做同等的事

  • 我使用Canny来检测边缘,然后Hough Lines转换以获得线条,我想我找不到适合我使用的正确参数。 你知道我该如何改进线路检测,最终只得到几条线路吗?

  • 关于ColorFilter()函数的一个简短问题;我正在尝试用新颜色替换图像的特定颜色: 所以在这个例子中,我只想用蓝色代替红色。但不要修改此图像的黑色。 从“porterduff”模式的描述来看,我应该使用“srv_atop”。但是我应该如何使用这个模式以便只替换红色呢?

  • 问题内容: 特别是我的图像在透明的情况下都是纯黑色的。我想在绘制图像时为图像分配简单的颜色,以便将黑色区域更改为新颜色。 我尝试使用仅返回所需颜色的RGBImageFilter,但出现了问题,根本没有绘制任何内容。(ColourFilter扩展了RGBImageFilter,并仅在其filterRGB()方法中返回设置的颜色。) 问题答案: 查看AlphaComposites,尤其是DST_IN: