专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 图形/图像

Python图像处理(四):滤波器

发布时间:2011-06-27 19:25:47 文章来源:www.iduyao.cn 采编人员:星星草
Python图像处理(4):滤波器

快乐虾

http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651)

欢迎转载,但请保留作者信息


滤波器在图像处理中的应用非常广泛,OpenCV也有个直接使用滤波器掩码(核)的函数filter2D,将图像与核进行卷积运算得到目标图像。卷积是在每一个图像块与某个算子(核)之间进行的运算,而核就是一个固定大小的数值数组。


实际上,在OpenCV中很多算法都是用卷积实现的,包括一些边缘检测的算法。本文无意列举这些算法的原理,仅仅是考察一下OpenCV的实现,再尝试用Python调用这些算法,看看其效果。


采用的测试图像还是它:


因为我们的最终目标是识别此图像中的杂草与棉花植株!


1.    FilterEngine


OpenCV中滤波的操作由FilterEngine这个类来完成,在源码的注释里清楚地说明了这个类的作用:


The Main Class for Image Filtering.

 The class can be used to apply an arbitrary filtering operation to an image.
 It contains all the necessary intermediate buffers, it computes extrapolated values
 of the "virtual" pixels outside of the image etc.
 Pointers to the initialized cv::FilterEngine instances
 are returned by various OpenCV functions, such as cv::createSeparableLinearFilter(),
 cv::createLinearFilter(), cv::createGaussianFilter(), cv::createDerivFilter(),
 cv::createBoxFilter() and cv::createMorphologyFilter().

 Using the class you can process large images by parts and build complex pipelines
 that include filtering as some of the stages. If all you need is to apply some pre-defined
 filtering operation, you may use cv::filter2D(), cv::erode(), cv::dilate() etc.
 functions that create FilterEngine internally.

下面是FilterEngine的一个典型使用方式:

void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
                      InputArray _kernelX, InputArray _kernelY, Point anchor,
                      double delta, int borderType )
{
    Mat src = _src.getMat(), kernelX = _kernelX.getMat(), kernelY = _kernelY.getMat();

    if( ddepth < 0 )
        ddepth = src.depth();

    _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
    Mat dst = _dst.getMat();

    Ptr<FilterEngine> f = createSeparableLinearFilter(src.type(),
        dst.type(), kernelX, kernelY, anchor, delta, borderType & ~BORDER_ISOLATED );
    f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 );
}

当然,如注释所说,我们几乎不需要直接使用这个类,但是了解它的用法对于我们理解和调试OpenCV是很有好处的。


2.    filter2D


下面试试直接给一个滤波器的矩阵看看效果。

# -*- coding: utf-8 -*- 
import cv2
import numpy as np

# filter2D

src = cv2.imread('f:\\tmp\\cotton.jpg')
cv2.imshow('src', src)

kernel = np.array([ [-1, -1, -1],
                    [-1,  8, -1],
                    [-1, -1, -1] ])

dst = cv2.filter2D(src, -1, kernel)
cv2.imshow('dst', dst)

cv2.waitKey()

结果就是这样的:



3.    PythonC++


看看从Pythonfilter2DFilterEngine的执行过程。


首先是filter2Dwrapper函数:

static PyObject* pyopencv_filter2D(PyObject* , PyObject* args, PyObject* kw)
{
    PyObject* pyobj_src = NULL;
    Mat src;
    PyObject* pyobj_dst = NULL;
    Mat dst;
    int ddepth=0;
    PyObject* pyobj_kernel = NULL;
    Mat kernel;
    PyObject* pyobj_anchor = NULL;
    Point anchor=Point(-1,-1);
    double delta=0;
    int borderType=BORDER_DEFAULT;

    const char* keywords[] = { "src", "ddepth", "kernel", "dst", "anchor", "delta", "borderType", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "OiO|OOdi:filter2D", (char**)keywords, &pyobj_src, &ddepth, &pyobj_kernel, &pyobj_dst, &pyobj_anchor, &delta, &borderType) &&
        pyopencv_to(pyobj_src, src, ArgInfo("src", 0)) &&
        pyopencv_to(pyobj_dst, dst, ArgInfo("dst", 1)) &&
        pyopencv_to(pyobj_kernel, kernel, ArgInfo("kernel", 0)) &&
        pyopencv_to(pyobj_anchor, anchor, ArgInfo("anchor", 0)) )
    {
        ERRWRAP2( cv::filter2D(src, dst, ddepth, kernel, anchor, delta, borderType));
        return pyopencv_from(dst);
    }

    return NULL;
}

这个函数是swig自动生成的,简单地对filter2D这个C++函数进行了包装,处理了输入参数和返回值。接着看cv::filter2D的实现过程:

void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
                   InputArray _kernel, Point anchor,
                   double delta, int borderType )
{
    Mat src = _src.getMat(), kernel = _kernel.getMat();

.....

    Ptr<FilterEngine> f = createLinearFilter(src.type(), dst.type(), kernel,
                                             anchor, delta, borderType & ~BORDER_ISOLATED );
    f->apply(src, dst, Rect(0,0,-1,-1), Point(), (borderType & BORDER_ISOLATED) != 0 );
}

和前面提到的sepFilter2D函数非常的相似!


cv::filter2D也是OpenCV开放的一个C++接口。












1楼u0100288695小时前
楼主总结的很详细,学习了 。nn欢迎关注,互相交流:http://blog.csdn.net/u010028869
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: