Python OpenCV - 显示坏像素检查测试

问题描述 投票:0回答:1

我想找到显示器中存在的每个坏像素。坏像素可能是颜色不正确的像素,或者像素只是黑色。显示屏的尺寸为 160x320 像素。所以如果显示效果好的话,必须有160*320=51200像素。如果显示器没有 51200 像素,那就是坏的。另外,我想知道每个坏像素的位置。

一旦拍摄的图像太大,我将共享一个谷歌驱动器共享文件夹,其中包含良好显示器和包含不良像素的不良显示器的示例。

显示图像

你能帮我怎么做吗?我想用 opencv 在 python 中做到这一点。

提前致谢

我尝试通过检测到的对象的轮廓进行评估,并且它有效,但前提是所有像素都存在。如果一个像素丢失并且没有检测到轮廓,我可以知道一个像素丢失,但我无法知道它的位置。

所以我认为最好的解决方案是跟踪网格并评估网格的每个单元。

这是我当前的代码:

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()
python python-3.x opencv machine-learning computer-vision
1个回答
0
投票

@吉列尔梅·门德斯

编辑:计算时间更少。 green-bad.bmp:35秒--->5秒

1.求轮廓质心

2.找到同一列的质心点

3.插入点于

坏像素

连接

好/坏像素

有蓝/红线

输入:green-bad.bmp

输出: c,r= 211 , 30 c,r= 211 , 30

输入:green-good.bmp

输出:无

#include <QtWidgets/QApplication>
#include <QPainter>
#include <QTimer>
#include <QDebug>
#include <vector>
#include <map>
#include<list>
#include <iterator>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;

class MyPoint3
{
public:
    MyPoint3(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z)
    {}
    int x, y, z;
    Point cvPoint()
    {
        return Point(x, y);
    }
    bool operator==(const MyPoint3& rhs)
    {
        return x == rhs.x && y == rhs.y && z == rhs.z;
    }
    MyPoint3(const MyPoint3& rhs)
    {
        x = rhs.x;
        y = rhs.y;
        z = rhs.z;
    }
    MyPoint3&operator=(const MyPoint3& rhs)
    {
        x = rhs.x;
        y = rhs.y;
        z = rhs.z;
        return *this;
    }
};
void findnearpts(vector<MyPoint3>&col,vector<MyPoint3>&pts, MyPoint3 ptrun)
{
    vector<MyPoint3> nearpts;
    pts.erase(find(pts.begin(), pts.end(), ptrun));
    col.push_back(ptrun);

    size_t j = 0;
    for (;j < pts.size()  ; j++)
    {
        auto iter0 = pts.at(j);
        if (iter0.x - ptrun.x > -8)
        {
            break;
        }
    }
    for (; j < pts.size()  ; j++)
    {
        auto iter0 = pts.at(j);
        if (iter0.x - ptrun.x > 8)
        {
            break;
        }
        if (fabs(ptrun.y - iter0.y) < 20)
        {
            nearpts.push_back(iter0);
        }
    }
    for (auto& a : nearpts)
    {
        findnearpts(col,pts, a);
    }
}
int main2(int argc,  char* argv[]);
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString str = "c:/Users/qt/Downloads/Displays-20230404T035654Z-001/Displays/";
    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,dst3;
    // 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);

    //morphologyEx(dst2, dst3, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(6,6)));
    //imwrite((str + "green-bad-binary-closing.bmp").toUtf8().constData(), dst3);
    //main2(argc, argv);
    vector<vector<Point> > contours0;
    vector<Vec4i> hierarchy;
    findContours(dst2, contours0, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);

    Mat matpt(src.size(), CV_8UC3,Scalar(0,0,0));
    typedef cv::Point3_<uint8_t> Pixel;
    vector<MyPoint3> points;
    for (auto& a : contours0)
    {
        auto M = moments(a);
        auto cx = int(M.m10 / M.m00);
        auto cy = int(M.m01 / M.m00);
        points.push_back(MyPoint3(cx, cy,0));
        line(matpt, Point(cx, cy), Point(cx, cy), Scalar(255, 255, 255));
    }
    imwrite((str + "green-bad-center.bmp").toUtf8().constData(), matpt);
    std::sort(points.begin(), points.end(), [&](MyPoint3 a, MyPoint3 b) {return a.x < b.x; });

    const int height = 160,width=320;


    vector<vector<MyPoint3>> cols;
    cols.reserve(width);
    for (;!points.empty();)
    {
        vector<MyPoint3> tmpcol;
        findnearpts(tmpcol, points, points[0]);
        cols.push_back(tmpcol);
    }
    qDebug() << "test1" << endl;
    for (auto& colrun : cols)
    {
        std::sort(colrun.begin(), colrun.end(), [&](MyPoint3 a, MyPoint3 b) {return a.y < b.y; });
    }
    qDebug() << "test2" << endl;
    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;
            }
        }
    }
    qDebug() << "test3" << endl;
    std::sort(cols.begin(), cols.end(), [&](vector<MyPoint3>& a, vector<MyPoint3>& b) {return a.at(0).x < b.at(0).x; });
    qDebug() << "test4" << endl;
    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);
    return a.exec();
}

© www.soinside.com 2019 - 2024. All rights reserved.