Python OpenCV -显示错误像素检查测试

gdx19jrr  于 2023-04-08  发布在  Python
关注(0)|答案(1)|浏览(112)

我想找到显示器中存在的每一个坏像素。坏像素可以是颜色不正确的像素,或者像素只是黑色。显示器的尺寸为160x320像素。因此,如果显示器是好的,必须有160*320 = 51200像素。如果显示器没有51200像素,那么就是坏的。此外,我想知道每个坏像素的位置。
一旦拍摄的图像太大,我会分享一个谷歌驱动器共享文件夹,里面有好的显示器和包含坏像素的坏显示器的例子。
Displays Images
你能告诉我怎么做吗?我想用python和opencv来做。
提前感恩
我试过通过检测到的物体的轮廓进行评估,它的工作原理,但只有当所有像素都存在。如果一个像素丢失,没有检测到轮廓,我可以知道一个像素丢失,但我不能知道它的位置。
所以我认为最好的解决方案是跟踪网格并评估网格的每个单元。
下面是我目前的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

def getColor(area):
    if area > 70:
        return (255, 0, 0)
    if area < 14:
        return (0, 0, 255)
    return (255, 255, 0)

def test_green_pattern():

    mask = cv2.imread("masks/mask.bmp", 0)
    green = cv2.imread("images/green-good.bmp")

    green_W = cv2.addWeighted(green, 3, green, 0, 1)

    gray = cv2.cvtColor(green_W, cv2.COLOR_BGR2GRAY)

    masked = cv2.bitwise_and(gray, gray, mask=mask)
    cv2.imwrite("try/green-masked.bmp", masked)
    # Real threshold = 120
    ret, thresh = cv2.threshold(masked, 120, 255, cv2.THRESH_BINARY)
    cv2.imwrite("try/green-threshold.bmp", thresh)

    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    print("Green Pattern Pixels:", len(contours))
    areas = []
    perimeters = []
    bad = 0
    prob_double = 0
    qtd = 0
    for i, contour in enumerate(contours):
        area = area = cv2.contourArea(contour)
        areas.append(area)
        perimeter = cv2.arcLength(contour,True)
        perimeters.append(perimeter)
        color = getColor(area)

        if area < 14:   
            bad += 1
            qtd += 1
            x, y, width, height = cv2.boundingRect(contour)
            roi = green[y:y+height, x:x+width]
            cv2.imwrite("try/temp/"+str(i)+".bmp", roi) 
            cv2.drawContours(green, contour, -1, color, 1)
            cv2.drawContours(green_W, contour, -1, color, 1)
        if area > 90:   
            prob_double += 1
            qtd += 2
            cv2.drawContours(green, contour, -1, color, 1)
            cv2.drawContours(green_W, contour, -1, color, 1)
        else:
            qtd += 1
    #get_statistics(areas, perimeters)
    print("Total:",qtd)
    print("Probably double pixel:", prob_double)
    print("Bad pixels:", bad)
    cv2.imwrite("try/green-contours.bmp", green)
    cv2.imwrite("try/green_w-contours.bmp", green_W)

test_green_pattern()
zkure5ic

zkure5ic1#

1.求轮廓质心
2.在同一列中查找质心点
3.插入点.
坏像素
连接
好/坏像素
蓝/红线
输入:green-bad.bmp
输出:c,r= 211,30 c,r= 211,30
输入:green-good.bmp
输出:无

QString str = "c:/Users/qt/Downloads/Displays-20230404T035654Z-001/Displays/";
    {
        auto green = imread((str + "green-good.bmp").toUtf8().constData());

        Mat green_W;
        addWeighted(green, 3, green, 0, 1, green_W);
        imwrite((str + "green-good-w.bmp").toUtf8().constData(),green_W);
    }
    auto src = imread((str+"green-bad.bmp").toUtf8().constData());
    //addWeighted(src, 3, src, 0, 1,src);
    imwrite((str + "green-bad-strong.bmp").toUtf8().constData(), src);
    Mat dst,dst2;
    // You can try more different parameters
    cvtColor(src, dst, COLOR_RGBA2GRAY, 0);
    imwrite((str + "green-bad-gray.bmp").toUtf8().constData(), dst);
    threshold(dst, dst2, 41, 255, THRESH_BINARY);
    imwrite((str + "green-bad-binary.bmp").toUtf8().constData(), dst2);

    vector<vector<Point> > contours0;
    vector<Vec4i> hierarchy;
    findContours(dst2, contours0, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    vector<MyPoint3> points;
    multimap<int, QPoint> pts,pts2;
    for (auto& a : contours0)
    {
        auto M = moments(a);
        auto cx = int(M.m10 / M.m00);
        auto cy = int(M.m01 / M.m00);
        //pts.insert(make_pair(cx, QPoint(cx, cy)));
        //pts2.insert(make_pair(cy, QPoint(cx, cy)));
        points.push_back(MyPoint3(cx, cy,0));
    }
    const int height = 160,width=320;
    vector<vector<MyPoint3>> cols;
    for (;!points.empty();)
    {
        MyPoint3 ptrun = *points.begin();
        for (size_t j = 1; j < points.size(); j++)
        {
            if (fabs(ptrun.x - points.at(j).x) < 8
                && fabs(ptrun.y - points.at(j).y) < 20)
            {
                int nfind = 0;
                vector<vector<MyPoint3>>::iterator iter;
                for (iter=cols.begin();iter!=cols.end();iter++)
                {
                    if ( find(iter->begin(), iter->end(), ptrun) != iter->end())
                    {
                        nfind = 1;
                        break;
                    }
                }
                if (nfind == 0)
                {
                    cols.push_back(vector<MyPoint3>{ptrun,points.at(j)});
                }
                else
                {
                    iter->push_back(points.at(j));
                }
            }
        }
        points.erase(points.begin());
    }
    for (auto& colrun : cols)
    {
        sort(colrun.begin(), colrun.end(), [&](MyPoint3 a, MyPoint3 b) {return a.y < b.y; });
    }
    for (int nfind = 1; nfind;)
    {
        for (size_t i = 0; i < cols.size(); i++)
        {
            if (cols.at(i).size() != height)
            {
                nfind = 1;
                for (size_t j = 0; j < cols.size(); j++)
                {
                    if (i != j
                        && cols.at(j).size() != height
                        &&
                        (fabs(cols.at(i).begin()->x - cols.at(j).rbegin()->x) < 8
                            || fabs(cols.at(i).rbegin()->x - cols.at(j).begin()->x) < 8
                            )
                        )
                    {
                        vector<MyPoint3> tmppts;
                        if (cols.at(i).begin()->y < cols.at(j).begin()->y)
                        {
                            tmppts.insert(tmppts.end(), cols.at(i).begin(), cols.at(i).end());
                            tmppts.insert(tmppts.end(), MyPoint3(cols.at(j).begin()->x, .5 * (cols.at(j).begin()->y + cols.at(i).rbegin()->y), 1));
                            tmppts.insert(tmppts.end(), cols.at(j).begin(), cols.at(j).end());
                        }
                        else
                        {
                            tmppts.insert(tmppts.end(), cols.at(j).begin(), cols.at(j).end());
                            tmppts.insert(tmppts.end(), MyPoint3(cols.at(i).begin()->x, .5 * (cols.at(j).rbegin()->y + cols.at(i).begin()->y), 1));
                            tmppts.insert(tmppts.end(), cols.at(i).begin(), cols.at(i).end());
                        }
                        if (i > j)
                        {
                            cols.erase(cols.begin() + i);
                            cols.erase(cols.begin() + j);
                        }
                        else
                        {
                            cols.erase(cols.begin() + j);
                            cols.erase(cols.begin() + i);
                        }
                        cols.push_back(tmppts);
                    }
                }
            }
            else
            {
                nfind = 0;
            }
        }
    }
    sort(cols.begin(), cols.end(), [&](vector<MyPoint3>& a, vector<MyPoint3>& b) {return a.at(0).x < b.at(0).x; });
    int colnumber = 0;
    for (auto& colrun : cols)
    {
        for (size_t i = 0; i+1 < colrun.size(); i++)
        {
            MyPoint3 p1 = colrun.at(i), p2 = colrun.at(i + 1);
            Scalar sc(255, 0, 0);
            if (p1.z || p2.z)
            {
                sc = Scalar(0, 0, 255);
                qDebug() << "c,r=" << colnumber << "," << (p1.z?i:i+1) << endl;
            }
            line(src,p1.cvPoint() ,p2.cvPoint(), sc);
        }
        colnumber++;
    }
    imwrite((str + "green-bad-cols.bmp").toUtf8().constData(), src);

相关问题