【问题标题】:ANDROID - color detection using openCV - how to?ANDROID - 使用openCV进行颜色检测 - 如何?
【发布时间】:2012-02-25 10:56:39
【问题描述】:

我的目标是使用 HSV 颜色空间以仅显示黄色对象的方式显示脱粒图像。我使用此代码(基于 openCV 2.3.1 android 示例给出的代码):

protected Bitmap processFrame(VideoCapture capture) {
    //capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
    //Imgproc.cvtColor(mGray, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

    capture.retrieve(mHSV, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    Imgproc.cvtColor(mHSV, mRgba, Imgproc.COLOR_RGB2HSV, 4);
    //Core.inRange(mRgba, new Scalar(20, 100, 100), new Scalar(30, 255, 255), mRgba);

    Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

    if (Utils.matToBitmap(mRgba, bmp))
        return bmp;

    bmp.recycle();
    return null;
}

基础(抽象)类包含“运行”方法:

protected abstract Bitmap processFrame(VideoCapture capture);

public void run() {
...
bmp = processFrame(mCamera);
...
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, (canvas.getHeight() - bmp.getHeight()) / 2, null);
...
}

我得到这个扭曲的预览,我认为我可以理解(HSV 格式),但为什么它会重复自己(我画一条绿线来强调它)4 次?什么是黑色水平线? 我做错了什么?

最后一件事,背后的逻辑是什么:

Imgproc.cvtColor(mHSV, mRgba, Imgproc.COLOR_RGB2HSV, 4);

为什么是 COLOR_RGB2HSV?不应该是 COLOR_HSV2RGB 吗?

假设我已经解决了这个问题,我怎样才能用黄色对象的原始颜色制作灰度图像?我想使用 Core.inRange() 方法,但是当我这样做时,我得到了黑屏。

是的,我想我看起来像个彻头彻尾的混蛋,但我需要从某个地方开始,不是吗?

10 倍!

更新 1: 我试着用这种方式做 RGB->HSV->RGB:

 @Override
protected Bitmap processFrame(VideoCapture capture) {
    //capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME);
    //Imgproc.cvtColor(mGray, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);

    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);
    Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_RGB2HSV,0);
    //Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_BGR2RGB, 4);
    //Core.inRange(mRgba, new Scalar(20, 100, 100), new Scalar(30, 255, 255), mRgba);
    Imgproc.cvtColor(mHSV,mRgba , Imgproc.COLOR_HSV2RGB,0);

    Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

    if (Utils.matToBitmap(mRgba, bmp))
        return bmp;

    bmp.recycle();
    return null;
}

我得到了:

?

更新 2:

我终于明白了,在设置一帧之前,必须先转换成RGBA空间。 所以我现在用如下代码尝试了阈值:

capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
    Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_RGB2HSV,0);
    Core.inRange(mHSV, new Scalar(20, 100, 100), new Scalar(30, 255, 255), mHSVThreshed);
    Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_HSV2RGB, 0);
    Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_RGB2RGBA, 0);
    Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);

但现在它让我强制关机......有什么想法吗?

【问题讨论】:

  • 我很久以前就知道了,这不是正确的提问方式——但你有没有为此做过教程?因为我无法让 VideoCapture 正常工作,如果你能在 github 上提供你的代码或部分代码,我会很高兴。非常感谢
  • 你好。我m really sorry but it has been a while since iv 与 openCV 合作,另外我没有代码了。我建议你看这里:docs.opencv.org/doc/tutorials/highgui/video-write/…。祝你好运,努力终有回报:)

标签: android opencv colors detection


【解决方案1】:

朋友。我给你1个月的努力和大洋彼岸朋友的帮助的结果:

Ethan 是对的。但代码需要一些修复。

代码:

    capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_BGRA);
    Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_BGR2HSV,3);
    Core.inRange(mHSV, new Scalar(0, 100, 30), new Scalar(5, 255, 255), mHSVThreshed);
    Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_GRAY2BGR, 0);
    Imgproc.cvtColor(mRgba, mRgba2, Imgproc.COLOR_BGR2RGBA, 0);
    Bitmap bmp = Bitmap.createBitmap(mRgba2.cols(), mRgba2.rows(), Bitmap.Config.ARGB_8888);


    if (Utils.matToBitmap(mRgba2, bmp))...

首先,mat 是二进制 0 或 255,因此转换为灰度更“自然”。第二,从HSV到RGB的转换其实就是HSV-BGR!!。最后一件事是预览需要 RGBA 位图。

就是这样。希望其他人可以从这篇文章中受益。沙洛姆!

【讨论】:

  • 赞,这帮了大忙!
  • @gor 能否请您添加 mRgba,mHSV,mHSVThreshed,mRgba2 的值?
  • 不确定我是否理解这个问题 + 这是几年前发布的,并且代码不再可访问..
  • 到许多 Imgproc.cvtColor... 所以对于 inRange 我们只需要 HSC 作为输入,GRAY 作为输出 (RGB2HSV) 和 (GRAY2RGB)
【解决方案2】:

我认为 mHSVThreshed 是一个二进制垫

所以也许这条线:

Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_HSV2RGB, 0);

应该改为:

Imgproc.cvtColor(mHSVThreshed, mRgba, Imgproc.COLOR_GRAY2RGB, 0);

我也花了很多时间处理“展示”问题...

希望对您有所帮助...

【讨论】:

  • 嘿,我想在图像中突出显示的部分添加一个矩阵,你能指导我吗?
  • 什么样的矩阵?你的意思是在上面画一些东西,比如 AR?
【解决方案3】:

据我所知,您获取 RGBA 中的图像帧并将其保存在名称“mHSV”下

capture.retrieve(mHSV, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

所以你应该把它存储为 mRgba

在 cvtColor 中,您需要通过 COLOR_RGBA2HSV 将其转换为 HSV。假设您更改了名称,这将是:

Imgproc.cvtColor(mRgba, mRSV, Imgproc.COLOR_RGB2HSV, 0);

并且我假设图像的这种重复来自 cvtColor 函数中的“4”,因为您的 HSV 图片将只有 3 个通道。在那里输入一个 0,它应该会被自动检测到......

希望对你有帮助……

【讨论】:

  • 嘿,正是我的意思,但有更好的解释:p
  • 您是否尝试调试以找出它究竟在哪里引发了错误?比如哪些命令似乎没有错误地完成,它在哪里退出?
  • 我做到了。显然该应用程序永远不会上线:Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_BGR2RGBA, 0);
  • 在主线程执行“mCamera.grab()”之前,几秒钟后它就崩溃了..
  • 完全不确定,但是当输入和输出指针实际上是同一个对象时,可能是 OpenCV 不喜欢它?两者都是 mRgba...
【解决方案4】:

为什么是 COLOR_RGB2HSV?不应该是 COLOR_HSV2RGB 吗?

我会说它应该:)。 看起来像opencv如何抓取像素的问题。检查您的输入和输出图像是否具有相同的大小和通道数。

这个

capture.retrieve(mHSV, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);

对我来说看起来也很奇怪,您是否将获得的 RGBA 图像存储为 HSV 格式的图像? 这将解释问题。 尝试做这样的事情:RGB(捕获检索)=> HSV(cvt color)=>颜色检测=> RGB(再次cvt颜色)

【讨论】:

  • 我知道它看起来是有线的,但是当我尝试转换时: capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_HSV2RGB_FULL, 4);它不起作用......
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2023-03-13
  • 1970-01-01
  • 2021-08-29
相关资源
最近更新 更多