从Image检测LED对象状态

jks*_*tar 4 opencv image-processing computer-vision

我的问题类似于OpenCV:检测视频输入中的 闪烁灯openCV检测闪烁的灯光

我想从任何有LED对象的图像中检测LED开/关状态.LED物体可以是任何尺寸(但主要是圆形).尽管可以打开或关闭,但是获取该图像中所有LED的位置非常重要.首先,我想获得只有ON的LED的状态和位置.现在,图像源对于我的工作是静态的,但它必须来自任何具有发光LED的产品的视频.所以没有机会让模板图像来减去背景.

我尝试过使用具有阈值,轮廓和圆圈方法的OpenCV(OpenCV新手),但没有找到成功.请分享是否有任何源代码或解决方案.解决方案可以是任何不仅使用OpenCV的东西,它会给我带来结果.这将不胜感激.

与其他两个问题的区别在于,我想获得图像中LED的数量,无论它是ON还是OFF以及所有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 );



}
Run Code Online (Sandbox Code Playgroud)

jle*_*and 7

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

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

并使用Python运行

$ cd image_processing/LedDetector/
$ python leddetector/led_highlighter.py
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到代码

我的方法:

  • 转换为一个频道图像
  • 搜索最亮的像素,假设我们至少有一个LED亮起并且背景为暗背景
  • 使用图像中最亮的部分创建二进制图像
  • 从图像中提取斑点,检索它们的中心和LED的数量.

此时代码只考虑了一个图像,但是你可以通过一个循环来增强它以获取一批图像(我已经在我的仓库中提供了一些示例图像.)你只需要在找到中心的地方玩一下对于LED,因为它们可能不是从一个图像到另一个图像精确的一个像素(中心可能稍微偏移).

为了使算法更加健壮(知道是否有LED亮,找到自动而非硬编码的边缘值),您可以使用直方图(放在extract_bright中)稍微玩一下.我已经创建了这个函数,你应该只需要增强它.

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

以下是图像的结果:

输入图片:

输入示例

二进制图像:

二进制结果(图像的最亮部分)

最后结果 :

最终结果(LED周围的边界框)

希望这可以帮助...

编辑:

如果要使用此图像,问题会稍微复杂一些.我发布的方法仍然可以使用,但需要稍微复杂化.

您想要检测显示"信息"(状态,带宽,...)的LED,并丢弃设计部分.

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

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

希望这能为思想带来更多的食物