image-processing - 从图像中检测 LED 对象状态

标签 image-processing opencv computer-vision

我的问题类似于OpenCV: Detect blinking lights in a video feed openCV detect blinking lights

我想从任何具有 LED 对象的图像中检测 LED 开/关状态。 LED 对象可以是任何大小(但主要是圆形)。获取该图像中所有 LED 的位置很重要,尽管它可以打开或关闭。首先,我想了解仅亮起的 LED 的状态和位置。现在图像源对于我的工作是静态的,但它必须来自任何具有发光 LED 的产品的视频。所以没有模板图像减去背景的机会。

我曾尝试将 OpenCV(OpenCV 的新功能)与阈值、轮廓和圆方法一起使用,但未发现成功。如果有任何源代码或解决方案,请分享。解决方案可以是任何东西,不仅可以使用 OpenCV 来为我提供结果。这将不胜感激。

与其他两个问题的不同之处在于,我想获取图像中的 LED 数量(是否可以打开或关闭)以及所有 LED 的状态。我知道这很复杂。首先,我试图检测图像中发光的 LED。我已经实现了我在下面分享的代码。我有不同的实现,但下面的代码能够通过绘制轮廓向我展示发光的 LED,但轮廓的数量比发光的 LED 多。所以我至少无法获得发光的 LED 总数。请向我建议您的意见。

int main(int argc, char* argv[])
{

IplImage* newImg = NULL;
IplImage* grayImg = NULL;
IplImage* contourImg = NULL;
float minAreaOfInterest = 180.0;
float maxAreaOfInterest = 220.0;
//parameters for the contour detection
CvMemStorage * storage = cvCreateMemStorage(0);
CvSeq * contours = 0;
int mode = CV_RETR_EXTERNAL;
mode = CV_RETR_CCOMP; //detect both outside and inside contour
cvNamedWindow("src", 1);
cvNamedWindow("Threshhold",1);
//load original image
newImg = cvLoadImage(argv[1], 1);

IplImage* imgHSV = cvCreateImage(cvGetSize(newImg), 8, 3);
cvCvtColor(newImg, imgHSV, CV_BGR2HSV);

cvNamedWindow("HSV",1);
cvShowImage( "HSV", imgHSV );
IplImage* imgThreshed = cvCreateImage(cvGetSize(newImg), 8, 1);

cvInRangeS(newImg, cvScalar(20, 100, 100), cvScalar(30, 255, 255), imgThreshed);
cvShowImage( "src", newImg );

cvShowImage( "Threshhold", imgThreshed );

//make a copy of the original image to draw the detected contour
contourImg = cvCreateImage(cvGetSize(newImg), IPL_DEPTH_8U, 3);
contourImg=cvCloneImage( newImg );
cvNamedWindow("Contour",1);
//find the contour
cvFindContours(imgThreshed, storage, &contours, sizeof(CvContour), mode, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
int i = 0;
for (; contours != 0; contours = contours->h_next)
{
    i++;
    //ext_color = CV_RGB( rand()&255, rand()&255, rand()&255 ); //randomly coloring different contours      
    cvDrawContours(contourImg, contours, CV_RGB(0, 255, 0), CV_RGB(255, 0, 0), 2, 2, 8, cvPoint(0,0));
}
printf("Total Contours:%d\n", i);
cvShowImage( "Contour", contourImg );

cvWaitKey(0);
cvDestroyWindow( "src" ); cvDestroyWindow( "Threshhold" );
cvDestroyWindow( "HSV" );
cvDestroyWindow( "Contour" );
cvReleaseImage( &newImg ); cvReleaseImage( &imgThreshed ); 
cvReleaseImage( &imgHSV );
cvReleaseImage( &contourImg );



}

最佳答案

我昨天晚上有时间,这是一个(非常)简单的部分解决方案,对我来说效果很好。 我创建了一个你可以直接克隆的 git 存储库:

git://github.com/jlengrand/image_processing.git

并使用 Python 运行

$ cd image_processing/LedDetector/
$ python leddetector/led_highlighter.py

可以看到代码here

我的方法:

  • 转换为一个 channel 图像
  • 搜索最亮的像素,假设我们至少有一个 LED 亮着,并且背景像您的图像一样暗
  • 用图像最亮的部分创建二值图像
  • 从图像中提取 Blob ,检索它们的中心和 LED 的数量。

代码此时只考虑图像,但您可以通过循环增强它以拍摄一批图像(我已经在我的 repo 中提供了一些示例图像。) 您只需稍微调整一下为 LED 找到的中心,因为从一张图像到另一张图像它们可能不准确(中心可能会稍微偏移)。

为了让算法更稳健(知道 LED 是否亮着,找到一个自动的而非硬编码的边距值),您可以尝试使用 直方图(放置在extract_bright)。 我已经为此创建了功能,您只需稍微增强一下即可。

关于输入数据的更多信息: Opencv 目前只接受 avi 文件,因此您必须将 mp4 文件转换为 avi(在我的例子中是未压缩的)。我用了this ,效果很好。 出于某种原因,queryframe功能导致我的计算机内存泄漏。这就是为什么我创建了 grab_images 函数,它将 avi 文件作为输入并创建一批 jpg 图像,您可以更轻松地使用它们。

这是一张图片的结果:

输入图像:

Input example

二值图像:

Binary result (brightest part of the image)

最终结果:

Final result (Bounding boxes surrounding the LEDs)

希望这对您有所帮助。 . .

编辑:

如果您想使用 this image,您的问题会稍微复杂一些.我发布的方法仍然可以使用,但需要稍微复杂一些。

您想检测显示“信息”(状态、带宽等)的 LED 并丢弃设计部分。

我看到了三个简单的解决方案:

  • 您之前了解 LED 的位置。在这种情况下,您可以应用完全相同的方法,但在整个图像的精确部分(使用 cv.SetImageROI)。
  • 您对 LED 的颜色有预知(您可以在图像上看到有两种不同的颜色)。然后你可以搜索整个图像,然后应用颜色过滤器来限制你的选择。
  • 你之前没有知识。在这种情况下,事情变得有点复杂。我倾向于说无用的 LED 应该都具有相同的颜色,并且状态 LED 通常会闪烁。这意味着通过向该方法添加一个学习步骤,您可能能够看到实际上必须选择哪些 LED 是有用的。

希望这能带来更多思考

关于image-processing - 从图像中检测 LED 对象状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10702105/

相关文章:

python - 立体标定Opencv Python和视差图

opencv - 为什么转换为灰度opencv?

c++ - 内部编译器错误 : Segmentation fault On Raspberry Pi

图像配准(非刚性\非线性)

c++ - 在 C++ OpenCV 中的图像上制作 32x32 部分?

python - Python中的多线程缩略图生成

opencv - openCV 适合生产代码吗?

opencv - opencv如何在高斯混合中存储矩阵值?按什么顺序?

opencv - 有没有在 GPU 上实现并且缩放/旋转不变的检测器?

Python、OpenCV——对齐和叠加多个图像,一个接一个