相关疑难解决方法(0)

图像处理:"可口可乐罐"识别的算法改进

在过去的几年里,我参与过的最有趣的项目之一是关于图像处理的项目.我们的目标是建立一个能够识别可口可乐"罐头"的系统(请注意,我正在强调'罐头'这个词,你会在一分钟内看到原因).您可以在下面看到一个示例,其中可以使用缩放和旋转在绿色矩形中识别.

模板匹配

对项目的一些限制:

  • 背景可能非常嘈杂.
  • 可以具有任何规模旋转,甚至方向(在合理的限度内).
  • 图像可能有一定程度的模糊性(轮廓可能不完全笔直).
  • 图像中可能有可口可乐瓶,算法应该只检测罐头!
  • 图像的亮度可能会有很大差异(因此您不能过多依赖颜色检测).
  • 可以部分地隐藏在两侧或中间,可能部分地隐藏了一瓶后面.
  • 有可能是没有像在所有的,在这种情况下,你必须找到什么,写一条消息这样说.

所以你最终可能会遇到这样棘手的事情(在这种情况下,我的算法完全失败):

总失败

我不久前做了这个项目,并且做了很多乐趣,我有一个不错的实现.以下是有关我的实施的一些细节:

语言:使用OpenCV库在C++中完成.

预处理:对于图像预处理,即将图像转换为更原始的形式以给出算法,我使用了两种方法:

  1. 将颜色域从RGB更改为HSV并基于"红色"色调进行过滤,饱和度高于某个阈值以避免橙色样色,并过滤低值以避免暗色调.最终结果是二进制黑白图像,其中所有白色像素将表示与该阈值匹配的像素.显然,图像中仍有很多废话,但这会减少您必须使用的维度数量. 二值化图像
  2. 使用中值滤波进行噪声滤波(取所有邻居的中值像素值并用该值替换像素)以减少噪声.
  3. 使用Canny边缘检测过滤器在2个先前步骤之后获取所有项目的轮廓. 轮廓检测

算法:我为这个任务选择的算法本身取自本关于特征提取的神奇书籍,称为广义霍夫变换(与常规Hough变换有很大不同).它基本上说了几件事:

  • 您可以在不知道其解析方程的情况下描述空间中的对象(这是这种情况).
  • 它可以抵抗图像变形,例如缩放和旋转,因为它基本上会针对比例因子和旋转因子的每个组合测试图像.
  • 它使用算法将"学习"的基本模型(模板).
  • 轮廓图像中剩余的每个像素将根据从模型中学到的内容投票给另一个像素,该像素应该是对象的中心(就重力而言).

最后,你得到了一张投票的热图,例如,这里所有罐子轮廓的像素都会投票给它的引力中心,所以你会在同一个像素对应的投票中得到很多票.中心,并将在热图中看到如下峰值:

GHT

一旦你有了这个,一个简单的基于阈值的启发式可以给你中心像素的位置,你可以从中获得比例和旋转,然后围绕它绘制你的小矩形(最终的比例和旋转因子显然将相对于你原始模板).理论上至少......

结果:现在,虽然这种方法在基本情况下起作用,但在某些方面却严重缺乏:

  • 非常慢!我并没有强调这一点.处理30个测试图像需要将近一整天,显然是因为我有一个非常高的旋转和平移比例因子,因为一些罐子非常小.
  • 当瓶子出现在图像中时,它完全丢失了,并且由于某种原因,几乎总是发现瓶子而不是罐头(可能因为瓶子更大,因此有更多的像素,因此更多的选票)
  • 模糊图像也不好,因为投票在中心周围的随机位置以像素结束,因此以非常嘈杂的热图结束.
  • 实现了平移和旋转的方差,但没有取向,这意味着没有直接面对相机物镜的罐子被识别出来.

你能帮助我改进我的特定算法,只使用OpenCV功能来解决上面提到的四个具体问题吗?

我希望有些人也会从中学到一些东西,毕竟我认为不仅要问问题的人应该学习.:)

c++ algorithm opencv image-processing

1585
推荐指数
20
解决办法
18万
查看次数

如何使用Python在OpenCV中裁剪图像

我如何使用OpenCV裁剪图像,就像我之前在PIL中所做的那样.

关于PIL的工作示例

im = Image.open('0.png').convert('L')
im = im.crop((1, 1, 98, 33))
im.save('_0.png')
Run Code Online (Sandbox Code Playgroud)

但是我怎么能在OpenCV上做到这一点?

这是我试过的:

im = cv.imread('0.png', cv.CV_LOAD_IMAGE_GRAYSCALE)
(thresh, im_bw) = cv.threshold(im, 128, 255, cv.THRESH_OTSU)
im = cv.getRectSubPix(im_bw, (98, 33), (1, 1))
cv.imshow('Img', im)
cv.waitKey(0)
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

我想我错误地使用了getRectSubPix.如果是这种情况,请解释我如何正确使用此功能.

python opencv

184
推荐指数
7
解决办法
43万
查看次数

如何使用OpenCV2.0和Python2.6调整图像大小

我想使用OpenCV2.0和Python2.6来显示已调整大小的图像.我在http://opencv.willowgarage.com/documentation/python/cookbook.html上使用并采用了这个例子,但遗憾的是这段代码适用于OpenCV2.1,似乎没有在2.0上运行.这是我的代码:

import os, glob
import cv

ulpath = "exampleshq/"

for infile in glob.glob( os.path.join(ulpath, "*.jpg") ):
    im = cv.LoadImage(infile)
    thumbnail = cv.CreateMat(im.rows/10, im.cols/10, cv.CV_8UC3)
    cv.Resize(im, thumbnail)
    cv.NamedWindow(infile)
    cv.ShowImage(infile, thumbnail)
    cv.WaitKey(0)
    cv.DestroyWindow(name)
Run Code Online (Sandbox Code Playgroud)

既然我不能用

cv.LoadImageM
Run Code Online (Sandbox Code Playgroud)

我用了

cv.LoadImage
Run Code Online (Sandbox Code Playgroud)

相反,这在其他应用程序中没有问题.然而,cv.iplimage没有属性行,列或大小.任何人都可以给我一个提示,如何解决这个问题?谢谢.

python opencv resize image image-processing

147
推荐指数
5
解决办法
43万
查看次数

Android Studio中的OpenCV

我想在Android Studio的应用程序中使用OpenCV库.我按照这里的说明,但我得到错误

未找到名称"default"的配置

有什么不对?

我使用带有gradle 2.2.1的Android Studio 1.0.

android opencv gradle android-studio

136
推荐指数
5
解决办法
18万
查看次数

检测照片中纸张角落的算法

检测照片中发票/收据/纸张角落的最佳方法是什么?在OCR之前,这将用于后续的透视校正.

我目前的做法是:

RGB>灰色>带阈值的Canny边缘检测>扩张(1)>移除小物体(6)>清除边界物体>根据凸面区域挑选大型博客.> [角落检测 - 未实施]

我不禁想到必须有一种更强大的"智能"/统计方法来处理这种类型的细分.我没有很多训练样例,但我可能会得到100张图像.

更广泛的背景:

我正在使用matlab进行原型设计,并计划在OpenCV和Tesserect-OCR中实现该系统.这是我需要为此特定应用程序解决的许多图像处理问题中的第一个.因此,我希望推出自己的解决方案并重新熟悉图像处理算法.

以下是我想要算法处理的一些示例图像:如果您想接受挑战,那么大图像位于http://madteckhead.com/tmp

案例1 http://madteckhead.com/tmp/IMG_0773_sml.jpg 案例2 http://madteckhead.com/tmp/IMG_0774_sml.jpg 案例3 http://madteckhead.com/tmp/IMG_0775_sml.jpg 案例4 http:/ /madteckhead.com/tmp/IMG_0776_sml.jpg

在最好的情况下,这给出:

案例1 - canny http://madteckhead.com/tmp/IMG_0773_canny.jpg 案例1 - post canny http://madteckhead.com/tmp/IMG_0773_postcanny.jpg 案例1 - 最大的博客http://madteckhead.com/tmp/ IMG_0773_blob.jpg

但是在其他情况下很容易失败:

案例2 - canny http://madteckhead.com/tmp/IMG_0774_canny.jpg 案例2 - post canny http://madteckhead.com/tmp/IMG_0774_postcanny.jpg 案例2 - 最大的博客http://madteckhead.com/tmp/ IMG_0774_blob.jpg

提前感谢所有伟大的想法!我喜欢!

编辑:霍夫变换进展

问:什么算法会聚集霍夫线找到角落?根据答案的建议,我能够使用Hough变换,拾取线条并过滤它们.我目前的做法相当粗糙.我已经假设发票总是小于15度,与图像不对齐.如果是这种情况,我最终得到合理的线条结果(见下文).但我不完全确定一个合适的算法来聚集线(或投票)来推断角落.霍夫线不连续.并且在嘈杂的图像中,可以存在平行线,因此需要与线原点度量的某种形式或距离.有任何想法吗?

案例1 http://madteckhead.com/tmp/IMG_0773_hough.jpg 案例2 http://madteckhead.com/tmp/IMG_0774_hough.jpg 案例3 http://madteckhead.com/tmp/IMG_0775_hough.jpg 案例4 http:/ /madteckhead.com/tmp/IMG_0776_hough.jpg

opencv image-processing edge-detection image-segmentation hough-transform

91
推荐指数
5
解决办法
5万
查看次数

如何将RGB图像转换为numpy数组?

我有一个RGB图像.我想将它转换为numpy数组.我做了以下

im = cv.LoadImage("abc.tiff")
a = numpy.asarray(im)
Run Code Online (Sandbox Code Playgroud)

它创建一个没有形状的数组.我假设它是一个iplimage对象.

python opencv numpy image

85
推荐指数
9
解决办法
25万
查看次数

如何在OpenCV中定义Watershed的标记?

我正在用OpenCV为Android写作.我正在使用标记控制的分水岭分割类似于下面的图像,而无需用户手动标记图像.我打算使用区域最大值作为标记.

minMaxLoc()会给我价值,但我怎么能把它限制在我感兴趣的blob?我可以利用findContours()cvBlob blob 的结果来限制ROI并对每个blob应用最大值吗?

输入图像

opencv image-processing computer-vision image-segmentation watershed

67
推荐指数
3
解决办法
6万
查看次数

计算机视觉 - 用OpenCV过滤凸壳和凸面缺陷

我有处理数字信号的问题.我试图检测指尖,类似于此处介绍的解决方案:使用JavaCV进行手部和手指检测.

但是,我没有使用JavaCV而是使用OpenCV for android,这有点不同.我已经设法完成了本教程中介绍的所有步骤,但过滤了凸包和凸性缺陷.这是我的图像的样子:

分辨率640x480

这是另一个分辨率的图像:

第320x240号决议

你可以清楚地看到,有许多黄点(凸面船体)和许多红点(凸面效应).有时在2个黄点之间没有红点,这很奇怪(如何计算凸包?)

我需要的是创建类似于之前提供的链接的simillar过滤功能,但使用OpenCV的数据结构.

凸壳是MatOfInt的类型......凸性缺陷是MatOfInt4的类型......

我还创建了一些额外的数据结构,因为愚蠢的OpenCV在不同的方法中使用包含相同数据的不同类型的数据......

convexHullMatOfInt = new MatOfInt();
convexHullPointArrayList = new ArrayList<Point>();
convexHullMatOfPoint = new MatOfPoint();
convexHullMatOfPointArrayList = new ArrayList<MatOfPoint>();
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所做的,但效果不佳.问题可能是以错误的方式转换数据:

创建凸包和凸面缺陷:

public void calculateConvexHulls()
{
    convexHullMatOfInt = new MatOfInt();
    convexHullPointArrayList = new ArrayList<Point>();
    convexHullMatOfPoint = new MatOfPoint();
    convexHullMatOfPointArrayList = new ArrayList<MatOfPoint>();

    try {
        //Calculate convex hulls
        if(aproximatedContours.size() > 0)
        {
            Imgproc.convexHull( aproximatedContours.get(0), convexHullMatOfInt, false);

            for(int j=0; j < convexHullMatOfInt.toList().size(); j++)
                convexHullPointArrayList.add(aproximatedContours.get(0).toList().get(convexHullMatOfInt.toList().get(j)));
            convexHullMatOfPoint.fromList(convexHullPointArrayList);
            convexHullMatOfPointArrayList.add(convexHullMatOfPoint);    
        }
    } catch (Exception e) {
        // TODO Auto-generated …
Run Code Online (Sandbox Code Playgroud)

java android opencv computer-vision

47
推荐指数
1
解决办法
1万
查看次数

找不到长的org.opencv.core.Mat.n_Mat()错误使用OpenCV

我正在使用OpenCV for adaptiveThreshold.我使用OpenCV进行图像处理的代码如下:

imageMat=new Mat();
Utils.bitmapToMat(bmp, imageMat);
Imgproc.cvtColor(imageMat, imageMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(imageMat, imageMat, new Size(3, 3), 0);
Imgproc.adaptiveThreshold(imageMat, imageMat, 255,Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 5, 4);
Run Code Online (Sandbox Code Playgroud)

但是我在宣布Mat时遇到错误.喜欢:

No implementation found for long org.opencv.core.Mat.n_Mat() (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__)
        at org.opencv.core.Mat.n_Mat(Native Method)
        at org.opencv.core.Mat.<init>(Mat.java:24)
        at com.example.pial_pc.instantbookreview.ImageCapture$3.onPictureTaken(ImageCapture.java:105)
Run Code Online (Sandbox Code Playgroud)

作为OpenCV的新手,我并不清楚错误.这段代码所属的整个java类都在这里.

我该怎么做才能消除错误?

android opencv

32
推荐指数
4
解决办法
3万
查看次数

使用Android相机捕获图像后将Bitmap转换为Mat

Mat b = new Mat();
Bitmap bmp = getIntent().getExtras().getParcelable("image_send");

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display_image);
    Mat tmp = new Mat (bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC1);
    Utils.bitmapToMat(bmp, tmp);
    Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_RGB2GRAY);
    //Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_GRAY2RGB, 4);
    Utils.matToBitmap(tmp, bmp);

    iv = (ImageView) findViewById(R.id.imageView1);
    iv.setImageBitmap(bmp);
}
Run Code Online (Sandbox Code Playgroud)

无法显示bmp.我的应用程序在拍照后停止了.

android opencv bitmap mat

31
推荐指数
2
解决办法
5万
查看次数