《mastering opencv》第一章学习

《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
#endif

int _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);
}


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


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值