OpenCV实现图像膨胀

图像的膨胀与图像腐蚀是一对相反的过程,与图像腐蚀相似,图像膨胀同样需要结构元素用于控制图像膨胀的效果。结构元素可以任意指定结构的中心点,并且结构元素的尺寸和具体内容都可以根据需求自己定义。定义结构元素之后,将结构元素的中心点依次放到图像中每一个非0元素处,如果原图像中某个元素被结构元素覆盖,但是该像素的像素值不与结构元素中心点对应的像素点的像素值相同,那么将原图像中的该像素的像素值修改为结构元素中心点对应点的像素值。图像的膨胀过程示意图如图所示,图中左侧为待膨胀的原图像,中间为结构元素,首先将结构元素的中心与原图像中的A像素重合,将结构元素覆盖的所有像素的像素值都修改为1,将结构元素中心点依次与原图像中的每个像素重合,判断是否有需要填充的像素。原图像膨胀的结果如图中右侧图像所示。

图像膨胀数学表示形式如式(6.5)所示,通过公式可以发现,其实图像A的膨胀运算就是生成能够将结构元素B全部包含的图像。

膨胀函数

void dilate( InputArray src, OutputArray dst, InputArray kernel,
                          Point anchor = Point(-1,-1), int iterations = 1,
                          int borderType = BORDER_CONSTANT,
                          const Scalar& borderValue = morphologyDefaultBorderValue() );
  • src:输入的待膨胀图像,图像的通道数可以是任意的,但是图像的数据类型必须是CV_8U,CV_16U,CV_16S,CV_32F或CV_64F之一。
  • dst:膨胀后的输出图像,与输入图像src具有相同的尺寸和数据类型。
  • kernel:用于膨胀操作的结构元素,可以自己定义,也可以用getStructuringElement()函数生成。
  • anchor:中心点在结构元素中的位置,默认参数为结构元素的几何中心点
  • iterations:膨胀的次数,默认值为1。
  • borderType:像素外推法选择标志,取值范围在表3-5中给出。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。
  • borderValue:使用边界不变外推法时的边界值。

该函数根据结构元素对输入图像进行膨胀,在膨胀多通道图像时每个通道独立进行膨胀运算。函数的第一个参数为待膨胀的图像,图像通道数可以是任意的,但是图像的数据类型必须是CV_8U,CV_16U,CV_16S,CV_32F或CV_64F之一。函数第二个参数为膨胀后的输出图像,与输入图像具有相同的尺寸和数据类型。函数第三个和第四个参数都是与结构元素相关的参数,第三个参数为结构元素,膨胀时使用的结构元素尺寸越大效果越明显,第四个参数为结构元素的中心位置,第四个参数的默认值为Point(-1,-1),表示结构元素的几何中心处为结构元素的中心点。函数第五个参数是使用结构元素膨胀的次数,膨胀次数越多效果越明显,默认参数为1,表示只膨胀1次。函数第六个参数是图像像素外推法的选择标志,第七个参数为使用边界不变外推法时的边界值,这两个参数对图像中主要部分的膨胀操作没有影响,因此在多数情况下使用默认值即可。

简单示例

//
// Created by smallflyfly on 2021/6/18.
//

#include "opencv2/opencv.hpp"

#include <iostream>

using namespace cv;
using namespace std;

void drawResult(Mat im, int num, Mat stats, Mat centroids, const string& name) {
    for (int i = 1; i < num; ++i) {
        int x = centroids.at<double>(i, 0);
        int y = centroids.at<double>(i, 1);
        cout << x << " " << y << endl;
        circle(im, Point(x, y), 2, Scalar(0, 0, 255), -1);
        int xmin = stats.at<int>(i, CC_STAT_LEFT);
        int ymin = stats.at<int>(i, CC_STAT_TOP);
        int w = stats.at<int>(i, CC_STAT_WIDTH);
        int h = stats.at<int>(i, CC_STAT_HEIGHT);

        Rect rect(xmin, ymin, w, h);
        rectangle(im, rect, Scalar(255, 255, 255), 2);
        putText(im, to_string(i), Point(x+5, y), FONT_HERSHEY_SCRIPT_SIMPLEX, 0.3, Scalar(0, 0, 255), 1);
    }
    imshow(name, im);
}

int main() {
    Mat src = (
            Mat_<uchar>(6, 6) <<
                              0, 0, 0, 0, 255, 0,
                    0, 255, 255, 255, 255, 255,
                    0, 255, 255, 255, 255, 0,
                    0, 255, 255, 255, 255, 0,
                    0, 255, 255, 255, 255, 0,
                    0, 0, 0, 0, 255, 0
    );
    resize(src, src, Size(0, 0), 50, 50, INTER_NEAREST);
    Mat m1, m2;
    m1 = getStructuringElement(0, Size(3, 3));
    m2 = getStructuringElement(1, Size(3, 3));

    Mat dilateM1, dilateM2;
    dilate(src, dilateM1, m1, Point(-1, -1), 5);
    dilate(src, dilateM2, m2, Point(-1, -1), 5);

    imshow("src", src);
    imshow("dilateM1", dilateM1);
    imshow("dilateM2", dilateM2);

    Mat xbim = imread("xiaobai.jpg");
    Mat xbM1, xbM2;
    dilate(xbim, xbM1, m1, Point(-1, -1), 2);
    dilate(xbim, xbM2, m2, Point(-1, -1), 2);

    imshow("xbim", xbim);
    imshow("xbM1", xbM1);
    imshow("xbM2", xbM2);

    Mat im = imread("rice.jfif");
    resize(im, im, Size(0, 0), 0.6, 0.6);
    Mat im1 = im.clone();

    Mat gray;
    cvtColor(im, gray, CV_BGR2GRAY);
    Mat riceBin;
    threshold(gray, riceBin, 125, 255, THRESH_BINARY);

    Mat out, stats, centroids;
    int count1 = connectedComponentsWithStats(riceBin, out, stats, centroids, 8, CV_16U);
    drawResult(im, count1, stats, centroids, "no dilate");

    Mat dilateIm1, dilateIm2;
    dilate(riceBin, dilateIm1, m1, Point(-1, -1), 5);
    dilate(riceBin, dilateIm2, m2, Point(-1, -1), 5);

    int count2 = connectedComponentsWithStats(dilateIm1, out, stats, centroids, 8, CV_16U);
    drawResult(dilateIm1, count2, stats, centroids, "dilateIm1");
    int count3 = connectedComponentsWithStats(dilateIm2, out, stats, centroids, 8, CV_16U);
    drawResult(dilateIm2, count3, stats, centroids, "dilateIm2");

    waitKey(0);
    destroyAllWindows();

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • opencv 图像腐蚀和图像膨胀的实现

    语言:python+opencv 为什么使用图像腐蚀和图像膨胀 如图,使用图像腐蚀进行去噪,但是为压缩噪声. 对腐蚀过的图像,进行膨胀处理,可以去除噪声,并保持原样形状. 图像腐蚀 腐蚀主要针对的是二值图像,如只有0和1两个值, 两个输入对象:1原始二值图像,2卷积核 使用卷积核遍历原始二值图像,如果卷积核对应的元素值均为1,其值才为1,否则为0.如图,红色为卷积核. 腐蚀后的结果示意图见下面,效果是将边缘抹掉一部分. 使用方法:erode 中文翻译:侵蚀 处理结果=cv2.erode(原始图像

  • OpenCV实现图像膨胀

    图像的膨胀与图像腐蚀是一对相反的过程,与图像腐蚀相似,图像膨胀同样需要结构元素用于控制图像膨胀的效果.结构元素可以任意指定结构的中心点,并且结构元素的尺寸和具体内容都可以根据需求自己定义.定义结构元素之后,将结构元素的中心点依次放到图像中每一个非0元素处,如果原图像中某个元素被结构元素覆盖,但是该像素的像素值不与结构元素中心点对应的像素点的像素值相同,那么将原图像中的该像素的像素值修改为结构元素中心点对应点的像素值.图像的膨胀过程示意图如图所示,图中左侧为待膨胀的原图像,中间为结构元素,首先将结

  • OpenCV+python实现膨胀和腐蚀的示例

    1,概念及原理: 膨胀(Dilating) (或) (1)将图像 A 与任意形状的内核 (B),通常为正方形或圆形,进行卷积. (2)内核 B 有一个可定义的 锚点, 通常定义为内核中心点. (3)进行膨胀操作时,将内核 B 划过图像A,将内核 B 覆盖区域的最大相素值提取,并代替锚点位置的相素.显然,这一最大化操作将会导致图像中的亮区开始"扩展" (因此有了术语膨胀 dilation ). 以3*3的内核为例: 腐蚀(Eroding) (与) (1)腐蚀在形态学操作家族里是膨胀操作的

  • C++ OpenCV实现图像去水印功能

    目录 前言 一.水印定位 二.图像修复 三.效果显示 四.源码 总结 前言 本文将使用OpenCV C++ 进行简单图像水印去除.我们在网上download图片时,经常因为版权问题有水印.本案例通过编写算法进行简单水印去除. 一.水印定位 如图所示,图像左下角.右下角有水印.第一步,我们首先得定位水印所在位置. Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); //图像二值化,筛选出白色区域部分 Mat thresh; threshold(gray,

  • python opencv实现图像边缘检测

    本文利用python opencv进行图像的边缘检测,一般要经过如下几个步骤: 1.去噪 如cv2.GaussianBlur()等函数: 2.计算图像梯度 图像梯度表达的是各个像素点之间,像素值大小的变化幅度大小,变化较大,则可以认为是出于边缘位置,最多可简化为如下形式: 3.非极大值抑制 在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点.对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的.如下图所示: 4.滞后阈值 现在要确定那些边界才是真正的

  • Python Opencv实现图像轮廓识别功能

    本文实例为大家分享了python opencv识别图像轮廓的具体代码,供大家参考,具体内容如下 要求:用矩形或者圆形框住图片中的云朵(不要求全部框出) 轮廓检测 Opencv-Python接口中使用cv2.findContours()函数来查找检测物体的轮廓. import cv2 img = cv2.imread('cloud.jpg') # 灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化 ret, binary = cv2.th

  • java通过jni调用opencv处理图像的方法

    1. 建立java文件 public class getImageFeature { static{ System.loadLibrary("getImageFeatureDll"); } public native int getImageFeatureByName(String filename); public native int getImageFeatureByMemory(); public static void main(String[] args) { getIma

  • Opencv实现图像灰度线性变换

    本文实例为大家分享了Opencv实现图像灰度线性变换的具体代码,供大家参考,具体内容如下 通过图像灰度线性变换提高图像对比度和亮度,原图像为src,目标图像为dst,则dst(x,y) = * src(x,y) + . 不仅对单通道图像可以做灰度线性变换,对三通道图像同样可以. #include<opencv2/opencv.hpp>; #include<iostream> using namespace cv; using namespace std; int main(int

  • python opencv对图像进行旋转且不裁剪图片的实现方法

    最近在做深度学习时需要用到图像处理相关的操作,在度娘上找到的图片旋转方法千篇一律,旋转完成的图片都不是原始大小,很苦恼,于是google到歪果仁的网站扒拉了一个方法,亲测好用,再次嫌弃天下文章一大抄的现象,虽然我也是抄歪果仁的. 废话不多说了,直接贴代码了. def rotate_bound(image, angle): # grab the dimensions of the image and then determine the # center (h, w) = image.shape[

  • Java OpenCV实现图像镜像翻转效果

    本文实例为大家分享了Java OpenCV实现图像镜像翻转效果的具体代码,供大家参考,具体内容如下 主要使用OpenCV的flip()方法,可以实现图像的垂直.水平以及同时垂直镜像翻转. flip是Core的静态方法,用法为: public static void flip(Mat src, Mat dst, int flipCode) 参数说明: src:输入图像: dst:输出图像: flipCode: = 0 图像向下翻转 > 0 图像向右翻转 < 0 图像同时向下向右翻转 代码如下:

随机推荐