对于大学,我们已经给出了一个任务,在给定图像的情况下,我们必须识别"数字",它们的颜色以及它们内部的"像素组"的数量.让我解释:

上面的图像有一个图形(在图像中可以有多个图形,但让我们暂时忘记它).
我们已经给出了一个能够拍摄图像并将它们转换为矩阵的类(每个元素是表示像素颜色的整数).
就是这样.我是用Java做的.
我做了什么
initialPixel从现在开始我会调用这个像素.initialPixel我提供的图像中的黑色像素位于图的左上角.我有目的地在那里做了一个尖锐的切口来说明它.但是我找到这样的背景颜色(白色)会遇到很多麻烦.这是我做的最接近的方法,适用于某些情况 - 但不适用于此图像:
initialPixel.听起来好像是个好主意 - 它确实有效,但它不适用于所提供的图像:在这种情况下它将返回黄色,因为initialPixel它远离图形的内容.假设我确实找到了图形的背景颜色(白色),我的下一个任务就是要意识到图中存在两个像素组.这个似乎更容易:
我需要的
是的,我的问题是关于如何找到图形的背景颜色(请记住它可以与整个图像的背景颜色相同 - 现在它是黄色的,但它也可以是白色的)基于我之前描述的内容.
我不需要任何代码 - 我只是在为这样的代码思考一个合适的算法.边界可能有如此奇怪的不规则线条的事实正在扼杀我.
或者甚至更好:我一直都做错了吗?也许我根本不应该如此关注这一点initialPixel.也许一种不同的初始方法会起作用?有关于此类主题的文档/示例吗?我意识到有很多关于"计算机视觉"等的研究,但我对这个特殊问题找不到多少.
一些代码
我的函数检索带有所有数字的向量:*注意:Figure只是一个包含一些值的类,如背景颜色和元素数量.
public Figure[] getFiguresFromImage(Image image) {
Figure[] tempFigures = new Figure[100];
int numberOfFigures = 0;
matrixOfImage = image.getMatrix();
int imageBackgroundColor = matrixOfImage[0][0];
int pixel = 0;
for (int y = 0; y < matrixOfImage.length; ++y) {
for (int x = 0; x < matrixOfImage[0].length; ++x) {
pixel = matrixOfImage[y][x];
if (!exploredPixels[y][x]) {
// This pixel has not been evaluated yet
if (pixel != imageBackgroundColor ) {
// This pixel is different than the background color
// Since it is a new pixel, I assume it is the initial pixel of a new figure
// Get the figure based on the initial pixel found
tempFigures[numberOfFigures] = retrieveFigure(y,x);
++numberOfFigures;
}
}
}
}
// ** Do some work here after getting my figures **
return null;
}
Run Code Online (Sandbox Code Playgroud)
然后,显然,功能retrieveFigure(y,x)是我无法做到的.
笔记:
解决此问题的一种好方法是将图像视为图表,其中每个颜色填充区域都有一个节点(此答案中的“组件”)。
这是实现此方法的一种方法:
对于每个像素,如果未访问该像素,请对其执行泛洪填充算法。在填充期间,将每个已连接的像素标记为已访问。
现在,您应该在图像(或“组件”)中具有纯色区域的列表,因此您只需要弄清楚它们如何相互连接:
查找像素与背景颜色分量相邻的分量-这是图形边框。请注意,您可以通过找到具有0,0像素的成分来找到背景颜色成分。
现在,找到像素与新发现的“图边框”组件相邻的组件。将有两个这样的组件-选择一个不是背景的组件(即没有0,0像素的组件)。这是您的图形背景。
要查找像素组,只需计算与图形背景分量相邻的像素的分量数(当然忽略图形边界分量)
这种方法的优点:
为了确保您了解如何遍历组件及其邻居,下面是步骤5的示例伪代码实现:
List<Component> allComponents; // created in step 2
Component background; // found in step 3 (this is the component with the 0,0 pixel)
Component figureBorder; // found in step 4
List<Component> pixelGroups = new List<Component>(); // list of pixel groups
for each Component c in allComponents:
if c == background:
continue;
for each Pixel pixel in c.pixelList:
for each Pixel neighbor in pixel.neighbors:
if neighbor.getComponent() == figureBorder:
c.isPixelGroup = true;
int numPixelGroups = 0;
for each Component c in allComponents:
if (c.isPixelGroup)
numPixelGroups++;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4807 次 |
| 最近记录: |