使用cvtColor将单一颜色转换

11

我有一个颜色,想将其转换为另一种颜色空间。是否可以直接使用 cvtColor 转换 cv::Vec3f 而不创建 1x1 的 cv::Mat,并填充该像素,对 cv::Mat 使用 cvtColor,然后从输出中获取唯一的像素?我尝试了以下方法,但似乎无法将向量传递给它。

有什么建议吗?

#include <iostream>

#include <opencv2/opencv.hpp>

int main(int, char*[])
{
    cv::Vec3f hsv;
    hsv[0] = .9;
    hsv[1] = .8;
    hsv[2] = .7;

    std::cout << "HSV: " << hsv << std::endl;

    cv::Vec3b bgr;
    cvtColor(hsv, bgr, CV_HSV2BGR); // OpenCV Error: Assertion failed (scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F)) in cvtColor

    std::cout << "BGR: " << bgr << std::endl; 

    return EXIT_SUCCESS;
}

我也尝试过这个,但是出现了另一个错误:

#include <iostream>

#include <opencv2/opencv.hpp>

int main(int, char*[])
{
    cv::Mat_<cv::Vec3f> hsv(cv::Vec3f(0.7, 0.7, 0.8));

    std::cout << "HSV: " << hsv << std::endl;

    cv::Mat_<cv::Vec3b> bgr;

    cvtColor(hsv, bgr, CV_HSV2BGR); // OpenCV Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in create

    std::cout << "BGR: " << bgr << std::endl;

    return EXIT_SUCCESS;
}

@Nacho 不,我不明白那样做怎么能实现颜色空间转换?你能发一下代码展示如何使用它来进行颜色空间转换吗? - David Doria
为什么要使用 cvtColor?如果你只想转换一个向量,我认为编写一个转换函数会更容易。 - Quang Hoang
@QuangHoang 因为OpenCV已经有大量的转换代码编写了。由于所有的包装/边缘情况等,实现颜色转换通常相当棘手。 - David Doria
@callyalater 我已经在出错的行上发布了错误。 - David Doria
1
你的第二种方法是正确的。只需使用 cv::Mat_<cv::Vec3f> bgr;,因为源和目标必须具有相同的类型。此外,您可以使用 Mat3f,它是 Mat_<cv::Vec3f> 的 typedef。 - Miki
@Miki 很有趣你回复了 - 我今天早上刚看了你的个人资料,试图找出如何联系你。如果你对一些合同工作感兴趣,请给我留言 - 你可以在这里找到我的电子邮件地址:https://github.com/daviddoria - David Doria
1个回答

7

您的第二种方法是正确的,但是在中,源和目标类型不同,这会导致错误。

请确保和都是相同类型的,这里应该是:

#include <opencv2/opencv.hpp>
#include <iostream>

int main()
{
    cv::Mat3f hsv(cv::Vec3f(0.7, 0.7, 0.8));

    std::cout << "HSV: " << hsv << std::endl;

    cv::Mat3f bgr;
    cvtColor(hsv, bgr, CV_HSV2BGR); 

    std::cout << "BGR: " << bgr << std::endl;

    return 0;
}

您可以使用Mat3f来简化操作。它只是一个类型定义:

typedef Mat_<Vec3f> Mat3f;

是的,这是深度复制数据。是的,可能会减慢速度。最简单的方法是:1)不使用cvtColor,而是直接应用颜色转换;2)如果您有一个循环,您可能有很多Vec3f。您可以创建一个矩阵并传递整个矩阵而不需要循环。 - Miki
  1. 可以。您可以查看color.cpp来借用OpenCV的实现。据我所知,如果要使用cvtColor,则需要一个Matstd::vector对象。
  2. 如果您能展示一些代码以便我们了解您的想法,我们可以寻找一种高效的方法。
- Miki
这里有一个后续问题,基本上也展示了我正在做的事情(只是在整个像素图像上循环执行):http://stackoverflow.com/questions/35737942/bgr-to-hsv-and-back-again - 对此有什么想法吗?我们真的应该尝试更新文档(它只有前向范围:http://docs.opencv.org/3.0-beta/modules/imgproc/doc/miscellaneous_transformations.html#void%20cvtColor%28InputArray%20src,%20OutputArray%20dst,%20int%20code,%20int%20dstCn%29)。 - David Doria
看起来你正在混淆浮点数的范围[0,1]和无符号字符的范围[0,255]。另外,静态转换似乎是错误的。我明天会检查得更好;D - Miki
没错,static_cast 运行良好,因为 OpenCV 提供了不同类型 Vec 之间的转换运算符。我在那里发布了一个答案,现在它似乎按预期工作。我会让你知道邮件的情况;D - Miki
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接