《mastering opencv》第一章学习

来源:互联网 发布:淘宝传奇一条龙可靠吗 编辑:程序博客网 时间:2024/06/07 14:14

《mastering opencv》第一章学习

   学习的资料,《mastering opencv》,这本教程非常金典,编写者之一是opencv源码的重要贡献者。里面的例子都是非常经典,有趣,并且涉及的算法都是应用最广的。我建议阅读英文原著版。我英语只有4级,刚开始读是蛮吃力的,越到后面就越有意思。网上有很多的资源下载,并且有每章的源码。非常好用,下面是我的学习总结:

   第一章的名字叫 Cartoonifier and Skin Changer for Android,讲的内容差不多是这样的:如何将一张图片(最好是人脸图片)如何变成漂亮的素描图片。如何变成萌萌的卡通图片,更恐怖的是如何将一个看上去人畜无害的图片变成一个恐怖的图片,最后将一张图片变成外星人的图片。非常有意思,对,先啥也不说,看看效果:

界面:


素描处理:



卡通处理:


恐怖处理:



sobel滤波处理


结束界面:


下面是代码部分:

主函数:Cartoonnifier.cpp

/******************************************************************************   Cartoonifier.cpp, for Desktop.*   Converts a real-life camera stream to look like a cartoon.*   This file is for a desktop executable, but the cartoonifier can also be used in an Android / iOS project.*******************************************************************************   by Li jie, 2017.8.17*******************************************************************************   Ch1 of the book "Mastering OpenCV with Practical Computer Vision Projects"*   Copyright Packt Publishing 2012.*****************************************************************************/#include "stdafx.h"#include <stdlib.h>#include <stdio.h>#include <highgui.h>#include <cv.h> #include <iostream>#include "opencv2/opencv.hpp"#include "cartoon.h"            // Cartoonify a photo.#include "highgui.h"using namespace std;using namespace cv;const int DESIRED_CAMERA_WIDTH = 640;const int DESIRED_CAMERA_HEIGHT = 480;const char *windowName = "Cartoonifier";#if !defined DEBUG#define DEBUG 0#endifint _tmain(int argc, _TCHAR* argv[]){cout << "Cartoonifier, by Li Jie 2017.8.12" << endl;cout << "Converts real-life images to cartoon-like images." << endl;cout << "Compiled with OpenCV version " << CV_VERSION << endl;cout << endl;cout << "Keyboard commands (press in the GUI window):" << endl;cout << "    q:  Quit the program." << endl;cout << "    s:    change to sketch_img " << endl;cout << "    c:    change to cartoonifier_img." << endl;cout << "    e:    change to Evil /scary_img." << endl;cout << "    d:    change to Sobel_img." << endl;cout << endl;//namedWindow(windowName); // Resizable window, might not work on Windows.Mat src = imread("C:\\Users\\Administrator\\Desktop\\lenna.bmp",-1 );Mat dest;if (src.empty()){cout << "fial!"<<endl;return -1;}char Keyboard_commands[10];cin.getline(Keyboard_commands, 10);namedWindow("Src_img", WINDOW_AUTOSIZE);imshow("Src_img", src);//waitKey(20);switch (*Keyboard_commands){case 'q': return -1;case 's':{sketch_img(src, dest); cin.getline(Keyboard_commands, 10);}case 'c':{ cartoonifier_img(src, dest);         cin.getline(Keyboard_commands, 10);}case 'e':{ scary_img(src, dest);         cin.getline(Keyboard_commands, 10);}case 'd':{ Sobel_img(src, dest);         cin.getline(Keyboard_commands, 10);}default:{   cout << "You have entered a wrong order!Please re-enter!" << endl;}}destroyWindow("Src_img");return 0;}



接下来是函数实现部分:cartoon.cpp

#include "cartoon.h"//图片素描化处理void sketch_img(Mat src_img, Mat  disposed_img){Mat gray,edges;cvtColor(src_img, gray, CV_BGR2GRAY);//灰度medianBlur(gray, gray, MEDIAN_BLUR_FILTER_SIZE);//中值滤波,做平滑处理,即降噪Laplacian(gray, edges, CV_8U, LAPLACIAN_FILTER_SIZE);//Laplacian锐化threshold(edges, disposed_img, EDGES_THRESHOLD, 255, THRESH_BINARY_INV);//灰度图像进行阈值操作得到二值图像namedWindow("sketch_img", WINDOW_AUTOSIZE);imshow("sketch_img", disposed_img);waitKey(0);destroyWindow("sketch_img");}//图片卡通化处理void cartoonifier_img(Mat src_img, Mat disposed_img){Mat gray, edges;cvtColor(src_img, gray, CV_BGR2GRAY);//灰度medianBlur(gray, gray, MEDIAN_BLUR_FILTER_SIZE);//中值滤波,做平滑处理,即降噪Laplacian(gray, edges, CV_8U, LAPLACIAN_FILTER_SIZE);//Laplacian锐化threshold(edges, disposed_img, EDGES_THRESHOLD, 255, THRESH_BINARY_INV);//灰度图像进行阈值操作得到二值图像//上面的步骤与sketch_img()函数中一模一样//进行卡通化处理Mat smallImg;Size smallSize;Size size;size = src_img.size();smallSize.width = size.width / 2;smallSize.height = size.height / 2;smallImg = Mat(smallSize, CV_8UC3);resize(src_img, smallImg, smallSize, 0, 0, INTER_LINEAR);//图片的大小调整,即图像的缩放// Perform many iterations of weak bilateral filtering, to enhance the edges// while blurring the flat regions, like a cartoon.Mat tmp = Mat(smallSize, CV_8UC3);int repetitions = 7;for (int i = 0; i < repetitions; i++){int size = 9;double sigmaColor = 9;double sigmaSpace = 7;//Bilateral方法(双边滤波)ilateral blur相对于传统的高斯blur来说很重要的一个特性即可可以保持边缘(Edge Perseving),//这个特点对于一些图像模糊来说很有用,ps美女图像上的效果very good!bilateralFilter(smallImg, tmp, size, sigmaColor, sigmaSpace);bilateralFilter(tmp, smallImg, size, sigmaColor, sigmaSpace);}// Go back to the original scale.resize(smallImg, src_img, size, 0, 0, INTER_LINEAR);Mat dst;dst.setTo(0);//disposed_img就是每个字节上的一个标志,标志位=0,不copy;标志位!=0,则copy(按字节) src_img.copyTo(dst, disposed_img);namedWindow("cartoonifier_img", WINDOW_AUTOSIZE);imshow("cartoonifier_img", dst);waitKey(0);destroyWindow("cartoonifier_img");}//图片恐怖化处理void scary_img(Mat src_img, Mat disposed_img){Mat gray;cvtColor(src_img, gray, CV_BGR2GRAY);//灰度medianBlur(gray, gray, MEDIAN_BLUR_FILTER_SIZE);//中值滤波,做平滑处理,即降噪Size size = src_img.size();Mat mask = Mat(size, CV_8U);Mat edges = Mat(size, CV_8U);Mat edges2;Scharr(gray, edges, CV_8U, 1, 0);Scharr(gray, edges2, CV_8U, 1, 0, -1);edges += edges2;threshold(edges, mask, 12, 255, THRESH_BINARY_INV);medianBlur(mask, mask, 3);namedWindow("scary_img", WINDOW_AUTOSIZE);imshow("scary_img", mask);waitKey(0);destroyWindow("scary_img");}static void on_Sobel(int, void*);//Sobel边缘检测窗口滚动条的回调函数//原图,原图的灰度版,目标图Mat g_srcImage, g_srcGrayImage, g_dstImage;//Sobel边缘检测相关变量Mat g_sobelGradient_X, g_sobelGradient_Y;Mat g_sobelAbsGradient_X, g_sobelAbsGradient_Y;int g_sobelKernelSize = 1;//TrackBar位置参数 //图片Sobel 算子化处理void Sobel_img(Mat src_img, Mat disposed_img){g_srcImage = src_img;g_dstImage = disposed_img;Mat gray;Mat g_sobelGradient_X, g_sobelGradient_Y;Mat g_sobelAbsGradient_X, g_sobelAbsGradient_Y;int g_sobelKernelSize = 1;//TrackBar位置参数  cvtColor(src_img, gray, CV_BGR2GRAY);//灰度namedWindow("【效果图】Sobel边缘检测", CV_WINDOW_AUTOSIZE);createTrackbar("参数值:", "【效果图】Sobel边缘检测", &g_sobelKernelSize, 3, on_Sobel);on_Sobel(0, 0);}void on_Sobel(int, void*){// 求 X方向梯度Sobel(g_srcImage, g_sobelGradient_X, CV_16S, 1, 0, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);convertScaleAbs(g_sobelGradient_X, g_sobelAbsGradient_X);//计算绝对值,并将结果转换成8位// 求Y方向梯度Sobel(g_srcImage, g_sobelGradient_Y, CV_16S, 0, 1, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);convertScaleAbs(g_sobelGradient_Y, g_sobelAbsGradient_Y);//计算绝对值,并将结果转换成8位// 合并梯度addWeighted(g_sobelAbsGradient_X, 0.5, g_sobelAbsGradient_Y, 0.5, 0, g_dstImage);//显示效果图imshow("【效果图】Sobel边缘检测", g_dstImage);waitKey(0);}


嗯,以上是代码加效果部分!


原创粉丝点击