opencv学习day(2)--图像的减色算法、椒盐噪声、锐化处理

参考了这篇博客,加上了一些具体的实现

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

/*
	减色算法
*/
void colorReduce(Mat &image, int div=64)
{
	int row = image.rows;
	int col = image.cols * image.channels();

	for (int i = 0; i < row; i++)
	{
		uchar *data = image.ptr<uchar>(i);
		for (int j = 0; j < col; j++)
		{
			data[j] = data[j] / div * div + div / 2;
		}
	}
}

/*
	变灰度图
*/
void imgtoGray(Mat &image)
{
	int row = image.rows;
	int col = image.cols;

	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			int x=image.at<Vec3b>(i, j)[0]+image.at<Vec3b>(i, j)[1]+image.at<Vec3b>(i, j)[2];
			image.at<Vec3b>(i, j)[0]=x/3;
			image.at<Vec3b>(i, j)[1]=x/3;
			image.at<Vec3b>(i, j)[2]=x/3;
		}
	}
}

/*
	椒盐噪声
	@param n,为噪声个数
*/
void salt(Mat &image, int n)
{
	for (int k = 0; k<n; k++)
	{
		int i = rand() % image.rows;
		int j = rand() % image.cols;
		if (image.channels() == 1)
		{
			image.at<uchar>(i, j) = 255;
		}
		else if (image.channels() == 3)
		{
			image.at<Vec3b>(i, j)[0] = 255;
			image.at<Vec3b>(i, j)[1] = 255;
			image.at<Vec3b>(i, j)[2] = 255;
		}
	}
}

/*
	图像锐化,自动挡
*/
void sharpen2D(Mat &image, Mat &result) // 中间x5 减去上下左右
{
	//构造核
	Mat kernel(3, 3, CV_32F, Scalar(0));
	//对核元素进行赋值
	kernel.at<float>(1, 1) = 5.0;
	kernel.at<float>(0, 1) = -1.0;
	kernel.at<float>(2, 1) = -1.0;
	kernel.at<float>(1, 0) = -1.0;
	kernel.at<float>(1, 2) = -1.0;
	filter2D(image, result, image.depth(), kernel);
}
/*
	图像锐化,手动挡
*/
void sharpen(const Mat &image, Mat &result)
{
    result.create(image.size(),image.type());//为输出图像分配内容
    //处理除最外围一圈外的所有像素值
    for(int i=1; i<image.rows-1; i++)
    {
        const uchar * pre = image.ptr<const uchar>(i-1);//前一行
        const uchar * cur = image.ptr<const uchar>(i);//当前行,第i行
        const uchar * next = image.ptr<const uchar>(i+1);//下一行
        uchar * output = result.ptr<uchar>(i);//输出图像的第i行
        int ch = image.channels();//通道个数
        int startCol = ch;//每一行的开始处理点
        int endCol = (image.cols-1)* ch;//每一行的处理结束点
        for(int j=startCol; j < endCol; j++)
        {
            //输出图像的遍历指针与当前行的指针同步递增, 以每行的每一个像素点的每一个通道值为一个递增量, 因为要考虑到图像的通道数
            //saturate_cast<uchar>保证结果在uchar范围内
            *output++ = saturate_cast<uchar>(5*cur[j]-pre[j]-next[j]-cur[j-ch]-cur[j+ch]);
        }
    }
    //将最外围一圈的像素值设为0
    //result.row(0).setTo(Scalar(0));
    //result.row(result.rows-1).setTo(Scalar(0));
    //result.col(0).setTo(Scalar(0));
    //result.col(result.cols-1).setTo(Scalar(0));
}

int main()
{
	Mat img = imread("arnold_schwarzenegger.jpg");
	if (img.empty())
	{
		printf("Error: can't open picture!\n");
		return -1;
	}

	imshow("in", img);

	//减色处理
	Mat dst = img.clone();
	colorReduce(dst, 128);
	imshow("减色处理", dst);

	//椒盐噪声
	Mat dst1 = img.clone();
	salt(dst1, 5000);
	imshow("椒盐噪声", dst1);

	//图像锐化1
	Mat dst2 = img.clone();
	Mat dst3;
	sharpen(dst2, dst3);
	imshow("图像锐化_手写", dst3);

	//图像锐化2
	Mat dst4;
	sharpen2D(dst2, dst4);
	imshow("图像锐化", dst4);

    //变灰度图
	Mat dst5 = img.clone();
	imgtoGray(dst5);
	imshow("灰度图", dst5);
	waitKey(0);
	destroyAllWindows();

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值