opencv学习笔记(三)

在第二讲中,我介绍了如何操作每个像素,这次利用操作像素完成简单的图像处理操作。

首先从给图像加入椒盐噪声开始,椒盐噪声其实就是使图像的一些随机的像素为黑色(255)或者白色(0):

[cpp]  view plain copy
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/highgui/highgui.hpp>  
  3.   
  4. using namespace cv;  
  5. void salt(Mat& image, int n)  
  6. {  
  7.     for(int k=0; k<n; k++)  
  8.     {  
  9.         int i = rand()%image.cols;  
  10.         int j = rand()%image.rows;  
  11.           
  12.         if(image.channels() == 1)  
  13.         {  
  14.             image.at<uchar>(j,i) = 255;  
  15.         }  
  16.         else  
  17.         {  
  18.             image.at<Vec3b>(j,i)[0] = 255;  
  19.             image.at<Vec3b>(j,i)[1] = 255;  
  20.             image.at<Vec3b>(j,i)[2] = 255;  
  21.         }  
  22.     }  
  23. }  

在看主程序,主程序中通过中滤波来消除噪声的影响:

[cpp]  view plain copy
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/highgui/highgui.hpp>  
  3. #include <opencv2/imgproc/imgproc.hpp>  
  4.   
  5. using namespace cv;  
  6. void salt(Mat&, int n=3000);  
  7. int main()  
  8. {  
  9.     Mat image = imread("D:/picture/img.tif");  
  10.     salt(image, 500);  
  11.     cv::namedWindow("image");  
  12.     cv::imshow("image",image);  
  13.   
  14.     //测试用滤波的手段消除椒盐噪声  
  15.     Mat result;  
  16.     Mat kernel;  
  17.     int ddepth;  
  18.     int kernel_size;  
  19.     ddepth = -1;  
  20.     int ind = 0;  
  21.     while(true)  
  22.     {  
  23.         //每0.5秒刷新一次图像  
  24.         int c = waitKey(500);  
  25.         //按esc键退出程序  
  26.         if((char)c == 27)  
  27.         {  
  28.             break;  
  29.         }  
  30.   
  31.         kernel_size = 3+2*(ind%5);  
  32.         kernel = Mat::ones(kernel_size,kernel_size,CV_32F)/(float)(kernel_size*kernel_size);  
  33.         filter2D(image,result,ddepth,kernel);  
  34.         imshow("滤波结果",result);  
  35.         ind++;  
  36.     }  
  37.       
  38.       
  39.     waitKey(0);  
  40. }  


可以看出,滤波器的核越大,对于噪声消除效果越好,但图像轮廓也越模糊。



 

图像的翻转:

[cpp]  view plain copy
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/highgui/highgui.hpp>  
  3. #include <iostream>  
  4.   
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. int main()  
  9. {  
  10.     //声明一个变量来承载图片,大小为0*0  
  11.     Mat image ;  
  12.     cout<<"size:"<<image.size().height<<","<<image.size().width<<std::endl;  
  13.     //读取一幅图像  
  14.     image= imread("D:/picture/img.tif");  
  15.     if (!image.data)   
  16.     {   
  17.         std::cout<<"read image fail!"<<std::endl;  
  18.     }  
  19.     //创建名为“My Image”的图像窗口  
  20.     namedWindow("My Image");  
  21.     //显示一幅图像  
  22.     imshow("My Image",image);  
  23.     //等待按键:返回值为按键的asc码值或者-1(当等待时间到了时,如果没有按键按下)  
  24.     waitKey(0);  
  25.     Mat result;  
  26.     result.create(image.rows,image.cols,image.type());  
  27.     int rows = image.rows;  
  28.     int cols = image.cols;  
  29.     //对图像做水平翻转  
  30.     for(int i = 0;i < rows;i++)  
  31.     {  
  32.         for(int j = 0;j < cols;j++)  
  33.         {  
  34.             result.at<Vec3b>(i,j)[0] = image.at<Vec3b>(i,cols-j-1)[0];  
  35.             result.at<Vec3b>(i,j)[1] = image.at<Vec3b>(i,cols-j-1)[1];  
  36.             result.at<Vec3b>(i,j)[2] = image.at<Vec3b>(i,cols-j-1)[2];  
  37.         }  
  38.     }  
  39.     //flip(image,result,1);//正值水平变换  
  40.                             //0垂直变换  
  41.                             //负值二者都有  
  42.       
  43.     namedWindow("output image");  
  44.     imshow("output image",result);  
  45.     waitKey(0);  
  46.       
  47.   
  48.     return 0;  
  49. }  


使用for循环完成的水平翻转效果与使用flip函数的效果相同。

接下来完成改变图像的对比度和亮度:

[cpp]  view plain copy
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/highgui/highgui.hpp>  
  3. #include <iostream>  
  4.   
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. //控制对比度  
  9. double alpha;  
  10. //控制亮度  
  11. int beta;  
  12.   
  13. int main()  
  14. {  
  15.     Mat image = imread("D:/picture/img.tif");  
  16.     if(!image.data)  
  17.     {  
  18.         cout<<"fail to read a image"<<endl;  
  19.         return -1;  
  20.     }  
  21.     Mat new_image = Mat::zeros(image.size(),image.type());  
  22.     cout << " Basic Linear Transforms " << endl;  
  23.         cout << "-------------------------" << endl;  
  24.         cout << "* Enter the alpha value [1.0-3.0]: ";  
  25.     cin>>alpha;  
  26.     cout << "* Enter the beta value [0-100]: ";  
  27.     cin>>beta;  
  28.     for(int i = 0;i < image.rows;i++)  
  29.     {  
  30.         for(int j = 0;j < image.cols;j++)  
  31.         {  
  32.             for(int c = 0;c < 3;c++)  
  33.             {  
  34.                 //由于运算结果可能不是整数,所以需要格式转换  
  35.                 new_image.at<Vec3b>(i,j)[c] = saturate_cast<uchar>(alpha*(image.at<Vec3b>(i,j)[c])+beta);  
  36.             }  
  37.         }  
  38.     }  
  39.     namedWindow("源图像");  
  40.     imshow("源图像",image);  
  41.     namedWindow("改变对比度和亮度的结果图像");  
  42.     imshow("改变对比度和亮度的结果图像",new_image);  
  43.     waitKey(0);  
  44.     return 0;  
  45. }  

最后是图像锐化:

[cpp]  view plain copy
  1. #include <opencv2\core\core.hpp>  
  2. #include <opencv2\highgui\highgui.hpp>  
  3. #include <opencv2/imgproc/imgproc.hpp>  
  4. using namespace cv;  
  5. int main()  
  6. {  
  7.     Mat image;  
  8.     image = imread("D:/picture/img.tif",0);//读取的是图像的灰度值,所以在sharpen函数中没有考虑通道数  
  9.     Mat result;  
  10.     result.create(image.rows,image.cols,image.type());  
  11.     //使用3*3滤波器,所以遍历的像素中不能包括图像最外围的一圈  
  12.     for(int i = 1;i < image.rows-1;i++)  
  13.     {  
  14.         //前一行、当前行、后一行的指针  
  15.         uchar* previous = image.ptr< uchar>(i-1);  
  16.         uchar* current  = image.ptr< uchar>(i);  
  17.         uchar* next     = image.ptr< uchar>(i+1);  
  18.         //输出结果图像的行指针  
  19.         uchar* output = result.ptr<uchar>(i);  
  20.         for(int j = 1;j < image.cols - 1;j++)  
  21.         {  
  22.             //图像锐化操作   
  23.             *output++= cv::saturate_cast<uchar>(5*current[j]-current[j-1]-current[j+1]-previous[j]-next[j]); //saturate_cast<uchar>会将小于0的置零,大于255的改为255  
  24.         }  
  25.     }  
  26.    result.row(0).setTo(cv::Scalar(0));  
  27.    result.row(result.rows-1).setTo(cv::Scalar(0));  
  28.    result.col(0).setTo(cv::Scalar(0));  
  29.    result.col(result.cols-1).setTo(cv::Scalar(0));  
  30.     /* 
  31.     //调用滤波函数来完成图像的锐化 
  32.     //滤波器的核 
  33.     Mat kernel(3,3,CV_32F,Scalar(0)); 
  34.     // 分配像素置 
  35.     kernel.at<float>(1,1) = 5.0; 
  36.     kernel.at<float>(0,1) = -1.0; 
  37.     kernel.at<float>(2,1) = -1.0; 
  38.     kernel.at<float>(1,0) = -1.0; 
  39.     kernel.at<float>(1,2) = -1.0; 
  40.     //调用滤波函数 
  41.     filter2D(image,result,image.depth(),kernel); 
  42.     */  
  43.     imshow("源图像",image);  
  44.     imshow("锐化结果",result);  
  45.     waitKey(0);  
  46.     return 0;  
  47. }  

个人觉得,对于灰度图像的锐化程序都有点长了,对于彩色图像就更麻烦了,还是直接调用滤波函数完成图像锐化比较方便

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值