OpenCV中文网站

 找回密码
 立即注册
搜索
热搜: 安装 配置
查看: 4227|回复: 8

LED 灯老化检测系统

[复制链接]
发表于 2016-9-18 13:36:21 | 显示全部楼层 |阅读模式
项目开发求教:LED灯珠检测
要求:LED灯珠正常是白色发光,不正常有3个状态:1,变暗  2,变黄  3,灭
          有个测试台平放灯珠正常发亮状态,要求系统定时拍照检测出哪个灯珠出现不正常状态,并记录变化时刻。

请教那位高手能够开发,请联系:QQ 397843957
回复

使用道具 举报

发表于 2016-9-18 14:00:57 | 显示全部楼层
本帖最后由 生如夏花 于 2016-9-18 14:39 编辑

你的qq有验证答案,做过多个led灯珠检测的案例,请联系qq  727647708
回复 支持 反对

使用道具 举报

发表于 2016-9-18 14:03:26 | 显示全部楼层
我做过类似的,检测LED颜色,亮灭,亮度等,希望合作,QQ:1252474285
回复 支持 反对

使用道具 举报

发表于 2016-9-18 15:11:14 | 显示全部楼层
老夫可以一试!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-20 18:21:54 | 显示全部楼层
stq054188 发表于 2016-9-18 14:03
我做过类似的,检测LED颜色,亮灭,亮度等,希望合作,QQ:1252474285

加你QQ要输入真实姓名???


回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-20 18:21:41 | 显示全部楼层
stq054188 发表于 2016-9-18 14:03
我做过类似的,检测LED颜色,亮灭,亮度等,希望合作,QQ:1252474285

加你QQ要输入真实姓名???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-20 18:21:56 | 显示全部楼层
stq054188 发表于 2016-9-18 14:03
我做过类似的,检测LED颜色,亮灭,亮度等,希望合作,QQ:1252474285

加你QQ要输入真实姓名???


回复 支持 反对

使用道具 举报

发表于 2016-9-25 20:16:42 | 显示全部楼层
1、变暗  =》灰度检测
2,变黄  =》查看蓝色分量数值,判断是否偏低
3,灭 =》 灰度检测
回复 支持 反对

使用道具 举报

发表于 2016-10-3 19:42:53 | 显示全部楼层
[size=26.6667px]

我将之前做过的项目手札找出来,应该有参考价值。需要注意的是LED本身是发光体,而且不同颜色本身波长不一样,那么获取它的图像的时候,可能要想办法获得问题的图像。



压板识别项目


零、相关说明:
     首先进行一下相关说明。在“jsxyhelu.cnblogs.com/项目实战派”栏目里面出现的需求、图片和其他资源,都是我在浏览威客网站、论坛等网站的时候通过正规渠道获得的真实需求。个人觉得比较感兴趣,但是由于时间或者工作的冲突自己没有去接这些项目。但是由于这些需求都很有实现价值,所以过了一段时间,仍然拿出来练一练手,并且实现了核心模块。希望能够给浏览者一些启发。如果你认为这些图片和资源放在这里不合适,请及时联系我(1755311380@qq.com),我会及时处理的。此外,我会将核心代码和技术细节尽可能将清楚,我认为这样才是最有价值的方式。如果需要原始代码,也可以和我联系。
一、原始需求/图片:
1.图片为保护压板正常方式投入,要求图像识别能正确判断,并将保护压板投退状态显示出来。
2.保护压板漏投(误投),要求图像识别能发现报警,并显示出是哪些保护压板漏投。
3.保护压板有投退异常现象,要求图像识别能发现报警,并显示出是哪些保护压板异常。
4.通过保护盘二维码(或条形码),要能识别出来保护盘柜名称
(正常情况下的图片)
(存在问题的图片1)
(存在问题的图片2)
二、初步分析:
其实需求主要是两个方面,一个是识别出压板的情况,二个是识别条码。
2.1识别压板:
常见的图像初步处理(换色彩域->OSTU->投影分析),对于初始的三幅图像,都能够得到比较干净的结果。但是这种情况过于理想了,在实
际项目中,需要考虑到由于其他原因引起的噪音,可能需要采用一定的方法去除噪音。此外,第5和第9个开关,采用的是和背景颜色比
较接近的压板,在实际项目中容易混乱,但是这个结果是原始需求直接关注的结果,可能要采用其他方法来强化  。



                                                                                                        (预处理结果)                     


                                                                      (投影运算结果)      
   
////第一个部分,获得各个压板区域的位置////
    //经过ostu运算,得到质量比较好的图像
    threshold(matSplit[1],ostu,100,255,THRESH_OTSU);
    dstclone = ostu.clone();
    // 做竖直的投影。这里由于更关心截断的情况,而不关心具体升降,所以是画出截断线而不是画波形
    for (int i=0;i<ostu.cols;i++)
    {
        Mat data = ostu.col(i);
        int itmp = countNonZero(data);
        vectorV.push_back(itmp);
    }
    //上波形为VUpper,下波形为VDown
    for (int i=1;i<vectorV.size();i++)
    {
        if (vectorV[i-1] == 0 && vectorV>0)
        {
            VUpper.push_back(i);
        }
        if (vectorV[i-1]>0 && vectorV == 0)
        {
            VDown.push_back(i);
        }
    }
   
    //计算结果
    for (int i=0;i<VUpper.size();i++)
    {
        Mat roitmp = ostu(Rect(VUpper,0,VDown-VUpper,ostu.rows));
        dilate(roitmp,roitmp,Mat());//对ostu的结果适当膨胀
        int uppertimes = 0;
        for (int j=0;j<ostu.rows;j++)
        {
            Mat data = roitmp.row(j);
            int itmp = countNonZero(data);
            vectorH.push_back(itmp);
        }
        for (int j=0;j<vectorH.size()-1;j++)
        {   
            if (vectorH[j]>0 && vectorH[j+1] == 0)
            {
                HDower.push_back(j);
            }
            if (vectorH[j] == 0 && vectorH[j+1]>0)
            {
                HUpper.push_back(j);
            }
        }
        if (HUpper.size() <= 1)
        {
            result = 1;
            //printf("结果为连在一起的\n");
        }
        else
        {   
            int iresult = 0;
            for (int j=0;j<HDower.size()-1;j++)
            {
                //得出之间空白的区域
                int iwidth = HUpper[j+1] - HDower[j];
                if (iwidth > 10)
                {
                    iresult = iresult +1;
                }
            }
            if (iresult > 0 )
            {
                result = 0;
               // printf("结果为断开的\n");
            }
            else
            {
                result = 1;
                //printf("结果为连在一起的\n");
            }
            iresult = 0;
        }
        vectorH.clear();
        HUpper.clear();
        HDower.clear();
        uppertimes = 0;
    }

    2.2条码识别:

    一般条码识别都依赖于现有的库(包括二维码,可以参考以前写过的一篇‘单向图像信息传输系统’和'ZXing一维二维编码解码'),图像处理方面需要做的主要是把条[size=16.2963px]码区域抠出来。由于条码它本身在设计的时候就是在竖直方向具备了冗余性,所以可以根据这个特性,采用形态学的方法将需要的区域采集出来。

[size=16.2963px]                                                       (canny处理并且经过形态学强化)      [size=16.2963px]

(最终取出来的结果)      


(条码解码)   

[size=16.2963px]

[size=16.2963px]

[size=16.2963px]


////第二个部分,获得条码区域////

    Mat sobel;

    Mat canny;

    Mat canny_output;

    int imax = 0;

    int imaxcontour = -1;

    std::vector<std::vector<cv::Point>>contours;              

    Mat cannyClone= Mat::zeros(Size(gray.cols,gray.rows),gray.type());

    Canny(gray,canny,100,255);

    Mat element = getStructuringElement(MORPH_ELLIPSE,Size(7,3));

    morphologyEx(canny,canny,CV_MOP_DILATE,element);

    morphologyEx(canny,canny,CV_MOP_ERODE ,element);

    findContours(canny,contours,CV_RETR_TREE,CV_CHAIN_APPROX_NONE);

    for (int i=0;i<contours.size();i++)

    {

        int itmp =  contourArea(contours);

        if (imaxcontour < itmp )

        {

            imax = i;

            imaxcontour = itmp;

        }

    }

    //找到轮廓的处理

    Rect boundRect;//最小外接矩形

    drawContours(cannyClone,contours,imax,Scalar(255),-1);

    boundRect = boundingRect(Mat(contours[imax]));

    Mat srcRoi = src(boundRect);

    imwrite("barcode.jpg",srcRoi);




三、难点攻关:
3.1第5和第9压板的特殊情况。
由于第5和第9压板的颜色和背景颜色非常接近,所以采用特殊的方法来进行处理。通过观察,结合常理。压板打开之后,必然带来的结果就
是下垂并且将下面的字符牌遮挡。那么可以通过反过来判断字符牌是否被遮盖来判断压板是否被打了下来。
   
                                                                                                       (字符遮挡)   

//将第5和第9条单独取出来

    Mat roi05 = src(Rect(6*VUpper[4],0,6*(VDown[4]-VUpper[4]),src.rows));

    Mat roi09 = src(Rect(6*VUpper[8],0,6*(VDown[8]-VUpper[8]),src.rows));

    cvtColor(roi05,roi05,CV_BGR2GRAY);

    cvtColor(roi09,roi09,CV_BGR2GRAY);

    threshold(roi05,roi05,100,255,THRESH_OTSU);

    threshold(roi09,roi09,100,255,THRESH_OTSU);

    threshold(roi05,roi05,0,255,THRESH_BINARY_INV);

    threshold(roi09,roi09,0,255,THRESH_BINARY_INV);

    std::vector<std::vector<cv::Point>>contours2;      

    findContours(roi05,contours2,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);

    int imax2 = 0;

    int imaxcontour2 = -1;

    for (int i=0;i<contours2.size();i++)

    {

        int itmp =  contourArea(contours2);

        if (imaxcontour2 < itmp )

        {

            imax2 = i;

            imaxcontour2 = itmp;

        }

    }

    Rect boundRect2;//最小外接矩形

    boundRect2 = boundingRect(Mat(contours2[imax2]));

    if (boundRect2.y+boundRect2.height >750)

    {

        //printf("第5个为打开的\n");

        result[4] = 0;

    }

    else

    {

        //printf("第5个为关闭的\n");

        result[4] = 1;

    }

    contours2.clear();

    findContours(roi09,contours2,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);

    imax2 = 0;

    imaxcontour2 = -1;

    for (int i=0;i<contours2.size();i++)

    {

        int itmp =  contourArea(contours2);

        if (imaxcontour2 < itmp )

        {

            imax2 = i;

            imaxcontour2 = itmp;

        }

    }

    boundRect2 = boundingRect(Mat(contours2[imax2]));

    if (boundRect2.y+boundRect2.height >750)

    {

        //printf("第9个为打开的\n");

        result[8] = 0;

    }

    else

    {

        //printf("第9个为关闭的\n");

        result[8] = 1;

    }




3.2倾斜情况下,条码识别错误
受到摄像头分辨率的限制,使得图像中条形码在倾斜的时候,受到插值算法的影响,边缘变得模糊。虽然尝试了许多方法,但是都无法达到
能够让zxing识别的程度。这个问题不知道哪位有更好的方法,如果可以的话,希望能够告之。
四、系统集成:
由于目前还没有很好地将zxing集成到mfc的环境中来。由于我对“csharp通过dll方式调用console程序”比较熟悉,所以这里尝试采用的是"csharp通过程序调用console的形式"。也就是主要图像处理的部分还是写的console程序,并且运算出相应的结果和图片,而后在csharp的程序中合并得到最后的结果。过程中发现这种方法的问题还是比较多的,包括参数的传递、程序重复运行时的控制等,应该说不是一种很成熟的方法,在以后面对类似的问题的时候,最好是能够直接将代码集成到mfc中,否则就要采用“csharp通过dll方式调用console程序”的方式。
最后的结果如下,并且可以多次测试都没有问题:

五、设计小结:
工作完成了,那么除了对代码进行重构并且提取出可以被重复使用的函数外,对于思路的小结也非常重要。在本例中:
5.1 提出了具有创造性的一个想法:采取分析下面的字符牌是否被遮挡的方式来判断开关闭合情况。逆向思维取得了稳定的结果;
5.2 对于色彩空间转换、对于投影的灵活运用构成了识别的主体。
不足的地方
5.3 对于一维/二维码识别没有构建稳定的库或解决方案,现在使用的zxing可以解决一部分问题,但是不过不了解原理,遇到不能解决的问题就无法继续优化;目前提取条码的方法应该被提出出来。
5.4 验证了"csharp通过程序调用console的形式"是不合算的。



回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站

GMT+8, 2024-4-26 15:39 , Processed in 0.014086 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表