一、题干

1. 题目背景

You have been given a contract by a factory that produces buttons. It is important that the factory identifies damaged buttons so that they are not supplied to the stores. The factory has a camera that takes a photo of buttons. The camera works only in black and white (no colour) and the resolution is not very good, but that is not a problem.
Your job is to write a C++ program that identifies any damaged buttons in the photo. You need to produce an image that displays a box around each button. If the button is damaged you must display a red box and if the button is not damaged you must display a green box. Make sure you read carefully through all the sections below.

译:
一家生产按钮的工厂给了你一份合同。重要的是,工厂要识别出损坏的按钮,这样它们就不会被提供给商店。这家工厂有一个可以用按钮拍照的照相机。这款相机只能使用黑白两种颜色(没有颜色),分辨率也不是很好,但这不是问题。你的工作是编写一个C++程序,以识别照片中任何损坏的按钮。您需要生成一个图像,在每个 按钮周围显示一个方框。如果按钮损坏,则必须显示一个红色框,如果按钮未损坏,则必须 显示一个绿色框。确保你仔细阅读了下面的所有部分。

2. Section A - input

The input to your program is the photo taken by the camera in the factory. Your program must be able to work with any such photo. Do not assume a specific number of buttons. do not assume that buttons will always be in the same place in the photo.(Hint: Before starting on your program, check that the .ppm file has no errors. Download Buttons.ppm from Stream and convert it to .bmp (or other format) and look at it. The display should look like this:

Just for interest – you can tell that the resolution of the camera is low because of the “stepped” edges to the buttons in the image. Actually, for many problems of this type (i.e. identifying defects in products) it is often better to use a black-and-white photo because the defects stand out more clearly

译:
程序的输入是工厂里的相机拍摄的照片。这可以在一个叫做Buttons.ppm文件中找到。 你的程序必须能够与任何这样的照片一起工作。不要假定有特定数量的按钮。不要假设按钮总 是在照片中的同一个位置。只是为了感兴趣——你可以看出相机的分辨率很低,因为在图像中的按钮的“阶梯式”边缘。实际上,对于许多这类问题(即。识别产品中的缺陷)通常最好使用黑白照片,因为缺陷更明显。

3. Section B – understanding the problem

Like many “real-life” systems, this type of project can never be perfect (which is what makes real-life projects interesting). We do the best we can by noting the following:
Notes about the problem:

  1. Buttons appear as white (or light grey) objects on a dark background. This is a black-and-white photo which means every pixel is a shade of grey (i.e. the R, G and B values are the same for each
    pixel). We define a pixel to be part of a button if its R (or G or B) value is greater than 128.
  2. There will always be a few pixels around the edge of a button (depending on the shadows) that are darker than this and will thus not count as part of the button. This does not matter.
  3. We need to know how to “identify” a button. Basically we look for pixels where the R value is greater than 128. But we need more than this – see next section below.
  4. To draw a box around a button you need to know the minimum and maximum x-value of all pixels in the button and also the minimum and maximum y-value of all pixels. The box then has a top left corner of (xmin, ymin) and a bottom right corner of (xmax, ymax) and so on.
  5. Some thought needs to be given to how we define a “damaged” button. This is entirely up to you.
    Hint: a damaged button will have less total pixels than an undamaged button.

译:
就像许多“现实生活”系统一样,这种类型的项目永远不会很完美 (这就是让现实生活中的项目很有趣的原因) 。我们会尽力注意以下几点:
1.按钮显示为深色背景上的白色(或浅灰色)对象。这是一张黑白相间的照片,这意味着每个像素都是一个灰色的阴影(即。每个像素的R、G和B值都是相同的)。如果一个像素的R(或G 或B)值大于128,则我们将其定义为该按钮的一部分。
2.在按钮的边缘总是有几个像素(取决于阴影)比这更暗,因此不能作为按钮的一部分。这并不重要。
3.我们需要知道如何“识别”一个按钮。基本上,我们在寻找R值大于128的像素。但我们需要更多,参见下面的下一节。
4.要在按钮周围画一个方框,你需要知道所有的最小值和最大x值 按钮中的像素,以及所有像素的最小值和最大y值。然后,方框有一个左上角(xmin, ymin)和一个右下角(xmax,ymax),以此类推。
5.我们需要考虑如何定义“损坏”按钮。这完全取决于你。 提示:损坏的按钮的总像素比未损坏的按钮少。

4. Section C – the algorithm to identify a button in the image

A button consists of pixels with R value greater than 128 AND the pixels must touch each other. If we work through every pixel, we can identify a button by:
a) finding a pixel with R value greater than 128
b) finding all other pixels that connect to that pixel (and have R value greater than 128)
c) go back to where we were in (a) and continue
The image below is trying to show this. Step (a) is shown in yellow. We start at the top left and work steadily across and down the image until we find a suitable pixel. Step (b) is shown in red – we find all pixels connected to the first one. Step © is shown in green – we go back to where we were at step (a)
and continue looking for pixels with R value greater than 128. Note that this diagram is to get the idea – the drawing is not perfect.

Now let us look at step (b) in more detail – if we have one pixel in the button, how do we find the others?
Assume that we have found pixel A at location (x, y) with an R value of greater than 128. Thus we know that pixel A is inside a button. We can then work through the pixels that touch pixel A (they are pixels B, C, D and E). Note the locations of these pixels. Pixel B is in the same row of the image as pixel A so has the same y value. But pixel B is one place to the left so it has a x value of x – 1. Pixel E is in the same vertical column of the image as pixel A so has the same x value. But pixel E is one place further down the screen so it has a y value of y + 1. Similarly for the other pixels.

Now that we know how to identify the “next door” pixels of pixel A, we have an algorithm as follows:
Find pixel A at location (x, y) and look for all connected pixels by:
Find pixel B at location (x – 1, y) and look for all connected pixels;
Find pixel C at location (x + 1, y) and look for all connected pixels;
Find pixel D at location (x, y – 1) and look for all connected pixels;
Find pixel E at location (x, y + 1) and look for all connected pixels;
This is a recursive algorithm – find the pixels connected to A by finding the pixels connected to B, . We could develop an infinite loop where pixel A checks pixel B which checks pixel A which checks pixel B, etc. And we solve the problem in the same way, i.e. we put a boolean into each pixel and as soon as we have checked a pixel we exclude it from the search. Do not check that pixel again.

Every recursive function needs a base case. In this case there are two which are:

  • return if the pixel you are checking has an R values of 128 or less
  • return if this pixel is excluded from the search (i.e. if this pixel has been checked before)

Some astute readers may have noticed that we are going on as if they are FOUR pixels next door to pixel A when in fact there are EIGHT next door pixels. We left out the diagonal pixels. The reason for this is that the recursion eventually works its way through all adjacent pixels. E.g. the pixel that is up and to the left of A is also above B so will be checked when B is checked.

译:
一个按钮由R值大于128的像素组成,且这些像素必须相互接触。如果我们通过每个像素进行工作,我们可以通过以下方式识别一个按钮:
a)查找R值大于128的像素
b)查找连接到该像素的所有其他像素(且R值大于128)
c)回到我们在(a)的地方,继续下去
下面的图片正试图展示这一点。步骤(a)用黄色表示。我们从左上角开始,稳定地穿过图像并向下工作,直到我们找到一个合适的像素。步骤(b)用红色表示——我们找到所有连接到第一个像素的像素。步骤©以绿色显示——我们回到步骤(a)的位置,继续寻找R值大于128的像素。请注意,这个图是为了得到这个想法——这个图并不完美。

现在让我们更详细地看看步骤(b)——如果我们在按钮中有一个像素,我们如何找到其他的像素 ?
假设我们在位置(x,y)上找到了R值大于128的像素A。因此,我们知道像素A就在一个按钮内。 然后我们可以处理触摸像素A的像素(它们是像素B、C、D和E)。请注意这些像素的位置。像素B 与像素A在图像的同一行中,因此具有相同的y值。但是像素B是左边的一个地方,所以它的x值是 x-1。像素E与像素A在图像的同一垂直列中,因此具有相同的x值。但是像素E是屏幕下方的一个地方,所以它的y值是y + 1。其他像素也是如此。

现在我们知道了如何识别像素A的“隔壁”像素,我们有了一个如下算法:
在位置(x、y)查找像素A,并通过以下方式查找所有连接的像素
查找位置(x-1(y))的像素B,并查找所有连接的像素;
在位置位置找到像素C(x+1,y),并查找所有连接的像素;
查找位置(x、y-1)查找像素D,并查找所有连接的像素;
在位置位置查找像素E(x,y+1),并查找所有连接的像素;

这是一个递归算法通过找到连接到B的像素来找到连接到a的像素,我们可以开发一个无限循环,其中像素A检查像素B,它检查像素A,它检查像素B。我们用同样的方法来解决这个问题。我们在每个像素中放一个布尔值,一旦我们检查了一个素素,我们就将它从搜索中排除。不要再次检查该像素。 每个递归函数都需要一个基本情况。在这种情况下,有两个方法,分别是: -如果您检查的像素R值不于128,则返回 -返回,如果这个像素被排除在搜索之外(如果之前已经检查过这个像素) 一些精明的读者可能已经注意到,我们就好像他们是A像素隔壁的4个像素,而实际上隔壁有8个像素。我们忽略了对角线像素。其原因是递归最终会通过所有相邻的像素。

5. Section D – program design

You MUST use the class called pixel_class. Note that two of the methods are at the end of the program. This class is as discussed in the notes but has an extra boolean variable called exclude to assist with the recursive function. This exclude variable is set to false at the start of the program and is set to true if this particular pixel has been checked.
You MUST use the following global variables:


int screenx, screeny, maxcolours;
pixel_class picture[600][600];


It is highly recommended that you also use the global variables:


int total, xmin, xmax, ymin, ymax; // these MUST be global


However, if you make the program work without these variables then you do not need to use them.

You MUST use the function called loadButtons exactly as it is in the program.
The rest is up to you. You can keep everything currently in the program or replace some of it as long as you use the compulsory sections of code listed above.
The basic outline of the main program is as follows: • load the photo data into the picture using the function loadButtons
• work through all pixels identifying buttons and placing boxes into the picture
• write the picture data to a new .ppm file
• (outside your program) convert your new .ppm file to .bmp and view it

译:
您必须使用被称为pixel_class的类。注意,其中两个方法在程序的结尾。这个类在注释中讨论 过,但是有一个额外的的布尔变量来帮助实现递归函数。这个排除变量在程序开始时被设置为false,如果检查了这个特定的像素,则被设置为true。
您必须使用以下全局变量:
int screenx, screeny, maxcolours;
pixel_class[600][600];
强烈建议您同时使用全局变量:
int total, xmin, xmax, ymin, ymax;//这些必须是全局的,
但是,如果你使程序工作没有这些变量,那么你就不需要使用它们。 你必须使用与程序中完全相同的被称为加载按钮的函数。 其余的则由你来决定。只要使用上面列出的代码的强制部分,就可以保留程序中的所有内容,或者替换部分。
主要程序的基本大纲如下:
使用功能加载按钮将照片数据加载到图片中
通过所有像素识别按钮和将盒子放置到图片中
将图片数据写入一个新的ppm文件
(在你的程序之外)转换你的新的ppm文件并查看它

6. Section E – output

The output from your program is an image stored in a .ppm file. In order to view the image you will probably need to convert it to a different format, e.g. a .bmp file.
The output image must show the buttons with boxes displayed around each button. The box must be red if the button is damaged and green if the button is acceptable. It should look like this:

Oh dear, this image shows only green boxes. This is not the correct result.
Note 1:
if you look very closely, you may see that some boxes do not perfectly sit around the button. There may be one or two pixels on the “wrong side” of the green line. Do not worry about this. Do not waste hours of time trying to get your boxes better than what is shown above. These boxes are perfectly adequate to show which button is being referred to.
Note 2:
you need to decide what defines a “damaged” button. Some buttons are obviously damaged, others may be ok, not quite sure about that. Welcome to programming in the real world! As long as the obviously damaged buttons are classified as damaged, that is ok. There may be one or two buttons that some people may regard as damaged and other people may not. In the real factory, the “damaged” buttons are checked by human experts before being discarded.

译:
程序的输出是存储在ppm文件中的图像。为了查看图像,您可能需要将其转换为一种不同的格式,例如bmp格式。输出图像必须显示按钮和每个按钮周围显示的方框。如果按钮损坏,则框必须为红色,如果按 钮可接受,则框必须为绿色。它应该是这样的:

这张图片只显示了绿色的盒子。这不是正确的结果。
注意1:如果你仔细观察,你可能会发现一些盒子并不完全坐在按钮周围。在绿线的“错误”可能 有一个或两个像素。不要担心这个问题。不要浪费几个小时的时间,试图让你的盒子比上面显示的更好。这些方框完全足以显示引用了哪个按钮。
注意2:您需要决定什么定义了一个“损坏的”按钮。有些按钮明显损坏了,有些可能还可以, 但不太确定。欢迎来到现实世界中的编程节目!只要明显损坏的按钮被归类为损坏,那就可以了。可能有一两个按钮,有些人可能认为损坏了,而其他人可能没有。在真正的工厂里,“损坏”的按钮在丢弃前由人工专家检查。

二、 给出待检测的PPM源文件

因无法上传PPM文件,给出链接,读者可自行下载。
链接:https://pan.baidu.com/s/1CdKYKQjP70k25l7nJCcLWA
提取码:LZ01

三、解答

1.题主的一些想法

(一)题主在阅读完题目后,便想到应用递归算法(但题主自己对递归算法理解尚浅,不对之处欢迎斧正)。

递归部分如何书写?

注下列均为对Pixel_Class而言

1.确定退出条件
  • 已经被访问过
  • 不符合为纽扣的一部分
2.递归顺序
  • 左->右->上->下
  • 右->左->下->上
  • and so on

与顺序无关,选一个你喜欢的就好,Select the You Like!

3.细枝末节

边界点的递归处理

(二)如何确定纽扣是否残缺的标准?(给出以下几个思路仅供参考)

1. 取图片内所有纽扣的像素平均值

低于平均像素值的纽扣即判读为缺陷
此判别方法问题在于:极值影响

2. 取图片内像素值最大的纽扣像素数量作为标准,允许向下波动,并设置允许波动的阈值。

此方法题主未写,若感兴趣读者可自己编写相应代码。

3. 人肉训练

计算出每一个纽扣的像素,通过分析数据找到合理的判断标准。(下面给出每个纽扣的像素总值和数据折线图)

纯纯人工操作了(不是我数的奥,我标的),希望技术可以再精湛,将此些工作均交给计算机操作。

具体完好纽扣像素标准还请读者自己测试。

(三)整个程序大致需要完成的任务

  • 设置一个像素类
  • 将源ppm文件读取到一个像素类数组
  • 处理这个数组
    • 递归处理每个纽扣
    • 判断是否,是符合要求的纽扣
      • 好的,画绿框
      • 坏的,画红框
  • 将处理好的象素类数组重新输出到一个新的ppm文件

(四)大致流程图示

2.给出一些重要代码片段

完整代码将在deadline结束后放出。题主也是个人,也得活。
代码片段可能涉及到一些前后关联问题,有问题欢迎留言。

(一) Pixel_class的定义

class pixel_class{private:int Red,Green,Blue;//每一个象素类有R,G,B三个值bool Lable;//用来标记是否被访问public://用来将R,G,B写入象素类void Load_RGB_to_pixel(int R,int G,int B){Red = R;Green = G;Blue = B;}//用来设置Lable初值bool Reset_Lable(bool initial){Lable = initial;}//用来判断是否被访问过bool Get_Lable(){return Lable;}//用来输入文件void Load_Pixel_to_ppmfile(fstream &OutFile){OutFile<<Red<<" "<<Green<<" "<<Blue<<" ";}//用来得到R,G,B三个值int Get_Red(){return Red;}int Get_Green(){return Green;}int Get_Blue(){return Blue;}
};

(二)LoadButtons Function

void loadButtons(string InFileName)
{fstream InFile;int Red,Green,Blue;InFile.open(InFileName.c_str(), fstream::in);//deal with error : can not oppen if(!InFile.is_open()){cout << "Warring! not able to open " << InFileName << endl;exit(2);}getline(InFile,FirstLine);  // get the first line "P3"getline(InFile,SecondLine);  // get the secondline "# filename"InFile >> screenx >> screeny;  // get the size of Screenx and ScreenyInFile >> maxcolours;  // this line is "256"for(int y = 0; y < screeny; y++){for(int x = 0; x < screenx; x++){InFile >> Red >> Green >> Blue;picture[x][y].Load_RGB_to_pixel(Red,Green,Blue);//by the way,reset every Pixel's Lable , make every pixels weren't visited  picture[x][y].Reset_Lable(false);}}InFile.close();
}

(三)CheckPixel Function

void CheckPixel(int x, int y)
{int Grayscale;bool Lable;Grayscale = picture[x][y].Get_Red();if (Grayscale <= 128  || picture[x][y].Get_Lable() == true) { picture[x][y].Reset_Lable(true);return; }total++; // to count the useful piexl number,用来记录符合要求得像素总数if (x < xmin) { xmin = x; }if (x > xmax) { xmax = x; }if (y < ymin) { ymin = y; }if (y > ymax) { ymax = y; }picture[x][y].Reset_Lable(true);  // resst it's Lable to promise do not check it again if (x > 0) { CheckPixel(x - 1, y); }if (y > 0) { CheckPixel(x, y - 1); }if (x < screenx - 1) { CheckPixel(x + 1, y); }if (y < screeny - 1) { CheckPixel(x, y + 1); }
}

(四)DrawBox Function

//记得选择你自己想画得颜色
void DrawBox(int R, int G, int B) {// do not check the pixels of the box - use lableint x, y;for(x = xmin; x <= xmax; x++){picture[x][ymin].Load_RGB_to_pixel(R, G, B);picture[x][ymin].Reset_Lable(true);picture[x][ymax].Load_RGB_to_pixel(R, G, B);picture[x][ymax].Reset_Lable(true);}for(y = ymin; y <= ymax; y++){picture[xmin][y].Load_RGB_to_pixel(R, G, B);picture[xmin][y].Reset_Lable(true);picture[xmax][y].Load_RGB_to_pixel(R, G, B);picture[xmax][y].Reset_Lable(true);}
}

(五)LoadPixelToNewPpmFile Fucntion

void load_picture_to_ppmfile(string OutFileName)
{OutFile.open(OutFileName.c_str(),fstream::out);if(!OutFile.is_open()){cout<< "Warring! not able to buit a new file " << OutFileName << endl;exit(2);}OutFile<<FirstLine<<endl;OutFile<<SecondLine<<OutFileName<<endl;OutFile<<screenx<<" "<<screeny<<endl;OutFile<<maxcolours<<endl;for(int y = 0; y < screeny; y++){for(int x = 0; x < screenx; x++){picture[x][y].Load_Pixel_to_ppmfile(OutFile);}OutFile << endl;}OutFile.close();
}

3.Answer

/* From LiuZhi_0101*/
#include<iostream>
#include<fstream>
#include <cstdlib>
using namespace std;
class pixel_class
{private:int Red,Green,Blue;bool Lable;public:void Load_RGB_to_pixel(int R,int G,int B){Red = R;Green = G;Blue = B;}bool Reset_Lable(bool initial){Lable = initial;}bool Get_Lable(){return Lable;}void Load_Pixel_to_ppmfile(fstream &OutFile){OutFile<<Red<<" "<<Green<<" "<<Blue<<" ";}int Get_Red(){return Red;}int Get_Green(){return Green;}int Get_Blue(){return Blue;}
};
//------------Must To Be Used Global Var-----------------------
int screenx,screeny,maxcolours;
pixel_class picture[600][600];
int xmin = 0,xmax = 0,ymin = 0,ymax = 0;
int total = 0;
//------------Own Global var--------------------------------
string FirstLine,SecondLine;//to record the fixed formatting
fstream OutFile;
//---------------------------------------------------
void loadButtons(string InFileName)
{fstream InFile;int Red,Green,Blue;InFile.open(InFileName.c_str(), fstream::in);//deal with error : can not oppen if(!InFile.is_open()){cout << "Warring! not able to open " << InFileName << endl;exit(2);}getline(InFile,FirstLine);  // get the first line "P3"getline(InFile,SecondLine);  // get the secondline "# filename"InFile >> screenx >> screeny;  // get the size of Screenx and ScreenyInFile >> maxcolours;  // this line is "256"for(int y = 0; y < screeny; y++){for(int x = 0; x < screenx; x++){InFile >> Red >> Green >> Blue;picture[x][y].Load_RGB_to_pixel(Red,Green,Blue);//by the way,reset every Pixel's Lable , make every pixels weren't visited  picture[x][y].Reset_Lable(false);}}InFile.close();
}
void CheckPixel(int x, int y)
{int Grayscale;bool Lable;Grayscale = picture[x][y].Get_Red();if (Grayscale <= 128  || picture[x][y].Get_Lable() == true) { picture[x][y].Reset_Lable(true);return;}total++; // to count the useful piexl numberif (x < xmin) { xmin = x; }if (x > xmax) { xmax = x; }if (y < ymin) { ymin = y; }if (y > ymax) { ymax = y; }picture[x][y].Reset_Lable(true);  // resst it's Lable to promise do not check it again if (x > 0) { CheckPixel(x - 1, y); }if (y > 0) { CheckPixel(x, y - 1); }if (x < screenx - 1) { CheckPixel(x + 1, y); }if (y < screeny - 1) { CheckPixel(x, y + 1); }
}
void DrawBox(int R, int G, int B) {// do not check the pixels of the box - use lableint x, y;for(x = xmin; x <= xmax; x++){picture[x][ymin].Load_RGB_to_pixel(R, G, B);picture[x][ymin].Reset_Lable(true);picture[x][ymax].Load_RGB_to_pixel(R, G, B);picture[x][ymax].Reset_Lable(true);}for(y = ymin; y <= ymax; y++){picture[xmin][y].Load_RGB_to_pixel(R, G, B);picture[xmin][y].Reset_Lable(true);picture[xmax][y].Load_RGB_to_pixel(R, G, B);picture[xmax][y].Reset_Lable(true);}
}
void load_picture_to_ppmfile(string OutFileName)
{OutFile.open(OutFileName.c_str(),fstream::out);if(!OutFile.is_open()){cout<< "Warring! not able to buit a new file " << OutFileName << endl;exit(2);}OutFile<<FirstLine<<endl;OutFile<<SecondLine<<OutFileName<<endl;OutFile<<screenx<<" "<<screeny<<endl;OutFile<<maxcolours<<endl;for(int y = 0; y < screeny; y++){for(int x = 0; x < screenx; x++){picture[x][y].Load_Pixel_to_ppmfile(OutFile);}OutFile << endl;}OutFile.close();
}
int main(){int x,y,grayscale;bool lable;
//-----------load Buttons.ppm file------------------------------loadButtons("Buttons.ppm");//----------jude every Buttons and draw boxs------------------------for (y = 0; y < screeny; y++) {for (x = 0; x < screenx; x++) {grayscale = picture[x][y].Get_Red();lable = picture[x][y].Get_Lable();if((grayscale > 128) && (lable == false)) {total = 0;xmin = x;xmax = x;ymin = y;ymax = y;CheckPixel(x, y);if(total < 7800){DrawBox(255, 0, 0);  // draw a red box}else{DrawBox(0, 255, 0);  // draw a green box}}}}
//------------------------------------------------------load_picture_to_ppmfile("NewButtons.ppm");
}

四、反思

题主自己的一些认识:
1.抽象了两层,象素类一层,遍历过程中纽扣看作一个整体,又是一层。
2.写一个感受到的词语,“吞噬”。遍历遇到一个符合要求的像素便可把整个纽扣找全。
3.数学基础很重要
4.someting interesting

//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//   我有大乘佛法三藏,能超亡者升天,能度难人脱苦,能解百魇之劫,能消无妄之灾。

C++程序设计(检测纽扣是否存在缺陷)相关推荐

  1. 趋高智能注塑件表面视觉检测之机器视觉的缺陷检测方案

    趋高智能注塑件表面视觉检测之机器视觉的缺陷检测方案. 趋高智能专注机器视觉软件硬件开发有10年以上的经验. 机器视觉是人工智能正在快速发展的一个分支.简单说来,机器视觉就是用机器代替人眼来做测量和判断 ...

  2. DLIA视觉缺陷检测平台——电子元器件焊点缺陷检测

    随着各类智能产品小型化设计,电路板上元器件的越来越多,任何产品在生产的时候或多或少都会产生少数外观不良,电子元器件当然也不例外.焊点缺陷是电路板生产制造过程中常见的问题,体积小.焊点密集是检查电路板焊 ...

  3. 实时获取ccd图像_四元数数控:CCD视觉检测定位系统在玻璃瓶缺陷的检测

    酷暑难耐,来一杯冰爽的饮料或者啤酒让人透心沁爽,无疑是消暑的好方法.通常,作为饮料或啤酒的容器多为塑料瓶或者玻璃瓶,而玻璃瓶作为一种可回收.更干净的盛装载体更受到许多人的青睐.在一些饮料或者是奶制品中 ...

  4. 【iPhone】缺陷检测机器视觉在制造业缺陷检测的应用情况

    机器视觉是通过计算机来模拟人类视觉功能,以让机器获得相关视觉信息和加以理解.可分为"视"和"觉"两部分原理,"视"是将外界信息通过成像来显示 ...

  5. python图像缺陷检测_python OpenCV 实现缺陷检测

    机器视觉第七次实验 一.实验目的 通过OpenCV第七次进行实验,对图片进行缺陷检测. 二.实验内容 对图片进行缺陷测量. 三.实验过程 我使用的是python语言+openCV对图片进行缺陷检测的功 ...

  6. [激光原理与应用-46]:《焊接质量检测》-3-焊接缺陷产生及常用焊缝无损检测方法

    目录 一.焊缝的内部缺陷类型 1.气孔 2.夹渣 3.裂纹 4.未焊透(虚焊) 5.未熔合(虚焊) 二.常见无损检测方法 1.超声波探伤: 2.射线探伤: 3.磁粉探伤 4.渗透探伤 一.焊缝的内部缺 ...

  7. [激光原理与应用-45]:《焊接质量检测》-2- 常见焊接缺陷与检验方法

    目录 一.概述 二.焊接缺陷的分类 2.1 按产生原因 2.2 按性质分有: 2.3 按在焊缝中的位置分有: 三.焊接缺陷检验的常用方法 一.概述 对于一个金属结构来说,焊接检验就是对所有焊缝或焊接接 ...

  8. 机器视觉检测技术在螺丝螺母缺陷检测中的应用

    目前市场上提出了基于机器视觉的检测方法.例如,对螺钉和非接触螺母的检查要求非常严格.另外,螺丝和螺母的使用量一般都很大,这一般是大规模生产.因此,随着计算机技术的发展,基于机器视觉的螺丝和螺母形状检测 ...

  9. 工业缺陷检测比赛Top3方案

    Datawhale干货 方向:深度学习,应用:工业缺陷检测 工业缺陷检测是当前深度学习落地的热门项目,近年来许多的比赛平台都举办了关于缺陷检测的比赛,如kaggle前不久举办的钢铁缺陷检测,以及天池刚 ...

最新文章

  1. matlab单机无限大系统_基于MATLAB的单机无穷大系统短路故障分析_吕鹏
  2. 使用 CrossOver 在 Linux运行 Windows 软件(金测OK)
  3. 细节决胜 盘点IBM x86平台虚拟化优势
  4. 单页面抓图并且保存的爬虫
  5. 家庭装修里最大的问题
  6. Solr6.1.0Windows安装步骤
  7. Nginx反向代理Redis服务
  8. usb禁止重定向_一种USB重定向处理方法和系统与流程
  9. 截取年月日在hana中怎么写_获取Sting类型格式-日期中的年月日
  10. linux sd卡 分区变大,Linux 动态调整分区大小
  11. Java char转换为String,String转换为char数组
  12. MODIS数据介绍及下载
  13. 【论文笔记】MOBA类游戏中的强化学习论文5篇
  14. 一切皆是文件:UNIX,Linux 操作系統的設計哲學
  15. python中ix用法_在python的pandas模块中,DataFrame对象,如何选择一行?索引、loc、iloc、ix的用法及区别...
  16. 小米小方摄像头云存储_小米摄像头离线?
  17. 时间序列-异常检测(Anomaly Detection)(四):深度学习方法
  18. 不吹不黑,三年赶超阿里云,华为这次是认真的!
  19. astar不能用了_截图快捷键,手把手教你截屏快捷键Ctrl+Alt+A不能用了怎么办
  20. 原码、补码以及正数/负数的左移和右移

热门文章

  1. 队列Q(Wannafly挑战赛19)
  2. HTML5 在线学习网站
  3. JVM学习总结笔记2
  4. 第三次作业 - 结对项目1
  5. 2021-07-09 支付行业发展特点与所面临的挑战需求
  6. 爬虫案例 王者荣耀 皮肤壁纸下载
  7. 中央民族大学计算机排名2015,2015年985大学排名排名汇总
  8. “I don’t understand” 表达 “我不明白”,太老土了!
  9. 蓝绿发布?灰度发布?滚动发布?
  10. java的书写规范_JAVA书写规范