iOS-OpenCV之蔡徐坤教你玩转边框画

栏目: 编程工具 · 发布时间: 5年前

内容简介:这一系列的文章已经写了第二篇了,所以这个系列将会转变为连载文章,每当我有什么新的发现,都会更新。本文demo地址:现在关于OpenCV的很多有趣的例子,都是python的。

这一系列的文章已经写了第二篇了,所以这个系列将会转变为连载文章,每当我有什么新的发现,都会更新。

本文demo地址: github.com/chouheiwa/O…

正文

现在关于OpenCV的很多有趣的例子,都是 python 的。

这篇文章的整体思路来源于 知乎 Maker毕 的文章: 蔡徐坤教你用OpenCV实现素描效果

上一篇文章中我们已经讲述过了,图像的存储,以及一些相关的信息。这篇文章就不会重复了,如果不是很清楚的读者可以看看第一篇文章。

这篇文章说是素描,其实与广义素描差距很大,准确的说应该是叫边框画。

先上一下效果图吧。

iOS-OpenCV之蔡徐坤教你玩转边框画

看起来是不是挺有意思的

步骤及原理

这里我们还是要先讲述一下步骤,这里先展示下原图

iOS-OpenCV之蔡徐坤教你玩转边框画

1. 将给定图片转灰度图

转成灰度图片的过程是为了消除其他影响因子(这一步也是很多图片处理|文字识别等相关领域的第一步)。

将图片从原来的三维层面,降到一维。

- (UIImage *)grayImage:(UIImage *)image {
    cv::Mat cvImage;

    UIImageToMat(image, cvImage);

    cv::Mat gray;
    // 将图像转换为灰度显示
    cv::cvtColor(cvImage, gray, CV_RGB2GRAY);

    cvImage.release();
    // 将灰度图片转成UIImage
    UIImage *nImage = MatToUIImage(gray);

    gray.release();

    return nImage;
}
复制代码

处理完毕后,我们能看到原来的蔡老师变灰了。

iOS-OpenCV之蔡徐坤教你玩转边框画

2. 对灰度图片进行高斯模糊

首先,先来讲一下如何进行简单的 模糊 处理

在上一篇文章中我们已经讲过了,图片其实就是一个二维数组。

所以图片上的每一个像素,都有一个像素数值。

我们可以以当前像素点为中心,取一个n * n的矩阵。

iOS-OpenCV之蔡徐坤教你玩转边框画

这里假定我们选了一个中心灰度值为190的像素点,它的周边像素的像素灰度值为100(255为纯白色)的3*3的像素矩阵

模糊处理的简单形式就是做平均,也就是将中间点的像素点和周围8个像素点的灰度值取平均值。也就是 (100 * 8 + 190) / 9 = 110

iOS-OpenCV之蔡徐坤教你玩转边框画

简单的模糊处理就是这么做的,不过 高斯模糊 是通过高斯函数去进行相应的计算,这里我找到了一篇相当好的文章: 高斯模糊

- (UIImage *)gaussianblurImage:(UIImage *)image {
    cv::Mat cvImage;

    UIImageToMat(image, cvImage);

    cv::Mat blur;
    // 选取一个5 * 5 的核用于模糊
    cv::GaussianBlur(cvImage, blur, cv::Size(5, 5), 0);
    cvImage.release();
    UIImage *blurImage = MatToUIImage(blur);
    blur.release();

    return blurImage;
}
复制代码

有一个模糊的蔡老师出现了

iOS-OpenCV之蔡徐坤教你玩转边框画

3. 对图像进行自适应二值化处理

这一步其实要讲的就是二值化,其实他的概念很简单。我们将灰度图上的某一个像素点的灰度值与给定的一个值进行比较,小于这个给定值的我们将其灰度值设置为0(黑色),大于的设置为255(白色)。我们给定的比较值被称之为 阈值

iOS-OpenCV之蔡徐坤教你玩转边框画

当然,这种二值化太过固化、死板。因为真实的照片有可能有阴影之类的遮挡,会导致我们的全局二值化,产生很多的误差,如下图右上角所示:

iOS-OpenCV之蔡徐坤教你玩转边框画

因此我们需要采用自适应二值化的方法,这里我们选择采用自适应高斯二值化(效果如上图右下角)

- (UIImage *)adaptiveThresholdImage:(UIImage *)image {
    cv::Mat cvImage;

    UIImageToMat(image, cvImage);

    cv::Mat outImage;

    cv::adaptiveThreshold(cvImage, outImage,
                          255,
                          cv::ADAPTIVE_THRESH_GAUSSIAN_C, // 这里我们采用的是高斯自适应模糊
                          cv::THRESH_BINARY, // 二值化
                          5,
                          2);

    cvImage.release();

    UIImage *adaImage = MatToUIImage(outImage);

    outImage.release();

    return adaImage;
}
复制代码

蔡老师的线条出现啦

iOS-OpenCV之蔡徐坤教你玩转边框画

4. 二值化图片进行再次模糊

现在蔡老师的衣服都已经变成线条了,基础的描边效果已经达成。但是我们可以看到,图片中比如说地面上,还有一些黑色的我们并不想要的点(我们称这些点为 噪点 )。以及蔡老师的线条还是有点细,所以我们需要将蔡老师的线条变粗些。

将上面的图片再次进行高斯模糊。

iOS-OpenCV之蔡徐坤教你玩转边框画

蔡老师变得模糊了

5. 对模糊图片再次进行二值化

这里我们再次进行二值化操作,因为现在图片已经相对干净,且并无阴影等干扰项。我们可以直接使用全局二值化来加深边框了(计算速度快)。

- (UIImage *)thresholdImage:(UIImage *)image {
    cv::Mat cvImage;

    UIImageToMat(image, cvImage);

    cv::Mat outImage;
    // 因为这时的图片已经比较干净且没什么阴影,所以选择普通二值化,灰度值 > 200 (这个值可以调,我觉得220效果更好) 的就赋值为255(白色)
    cv::threshold(cvImage, outImage, 200, 255, cv::THRESH_BINARY);

    cvImage.release();

    UIImage *threImage = MatToUIImage(outImage);

    outImage.release();

    return threImage;
}
复制代码
iOS-OpenCV之蔡徐坤教你玩转边框画

6. 对图片进行噪点去除

现在需要去除图片中的小的噪点,我们就需要进行一系列的操作了

关于这些操作,我们在图像处理方面有专门的名词描述:

腐蚀与 膨胀

腐蚀:

腐蚀通俗的来说,就是将原本的图像根据给定的核(为我们自定义的一种形状,一般为n*n的正方形,n为奇数)缩小。

iOS-OpenCV之蔡徐坤教你玩转边框画

只有当原本的图像上对应核心周围所有的点都有值时,我们才保留当前核心的值。

iOS-OpenCV之蔡徐坤教你玩转边框画

膨胀:

膨胀则正好相反,我们将给定的图片根据给定的核放大。

iOS-OpenCV之蔡徐坤教你玩转边框画

当我们扫描核的任意一点上有值时,当前核心点将会被赋值

iOS-OpenCV之蔡徐坤教你玩转边框画

腐蚀和 膨胀 便是我们这步处理的关键。

它们之间的组合被我们称之为 开运算闭运算

开运算

我们先对图片进行 腐蚀 运算,然后进行 膨胀 运算

最终效果将如上图的左下角结果

我们和原图进行比较可以发现。

开运算可以去除毛刺,小桥和孤立的小点(在 腐蚀 运算中小点会直接消失)。最终总的位置和形状不变( 膨胀 运算会恢复)

闭运算

闭运算这里因为我们不会用到,因此不会过多赘述。

它和开运算的过程相反,先对原图像进行 膨胀 运算后进行 腐蚀 运算。

我们的目的是处理图片中的一些噪点,因此我们采用开运算来处理。

- (UIImage *)morphologyImage:(UIImage *)image {
    cv::Mat cvImage;

    UIImageToMat(image, cvImage);
    // 将图片取反,原黑变白,原白变黑
    cv::bitwise_not(cvImage, cvImage);

    cv::Mat outImage;
    /// 获取一个3*3的核
    cv::Mat ken = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    /// 进行图像的开运算(开运算需要对有数值的地方进行缩小,所以我们需要将图片反色,即大部分有数值,而小部分没有,才能达到效果)
    cv::morphologyEx(cvImage, outImage, cv::MORPH_OPEN, ken);

    ken.release();

    cvImage.release();

    cv::bitwise_not(outImage, outImage);

    UIImage *morphologyImage = MatToUIImage(outImage);

    outImage.release();

    return morphologyImage;
}
复制代码

图片干净了很多

iOS-OpenCV之蔡徐坤教你玩转边框画

7. 最后进行一次高斯模糊

我们最后在进行一次高斯模糊,使我们的图像效果更好。

iOS-OpenCV之蔡徐坤教你玩转边框画

其他

视频的转换,这里就不多写了(正在研究过程中...)

这篇文章的对应demo请点击 网址 ,如果大家觉得还不错,请尽情的用你么的star来砸我。


以上所述就是小编给大家介绍的《iOS-OpenCV之蔡徐坤教你玩转边框画》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入应用C++11

深入应用C++11

祁宇 / 机械工业出版社 / 2015-5 / 79

在StackOverflow的最近一次世界性调查中,C++11在所有的编程语言中排名第二, C++11受到程序员的追捧是毫不意外的,因为它就像C++之父Bjarne Stroustrup说的:它看起来就像一门新的语言。C++11新增加了相当多的现代编程语言的特性,相比C++98/03,它在生产力、安全性、性能和易用性上都有了大幅提高。比如auto和decltype让我们从书写冗长的类型和繁琐的类型......一起来看看 《深入应用C++11》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具