OpenCV-11-C++获取图像属性、图像直方图绘制及均衡化、卷积和滤波

1. 获得图像属性
Mat src = imread("./lena.jpg");
//尺寸 
src.size(); 
//行数 
src.rows(); 
//列数 
src.cols(); 
//通道数 
src.channels(); 
//数据类型 
src.type();
2. Mat类的创建、矩形定义
Mat src = Mat::zeros(600,400,CV_8UC3); //8位无符号3通道
Mat dst(400,600,CV_8UC3);
//矩形类的定义
Rect rect(100,50,200,200);
3.数据操作:在图中划红线、访问mat类中的数据使用at()方法
// 在图片中间增加一根红色的线
for(int i=0;i<600;i++){
    dst.at<Vec3b>(200,i) = Vec3b(0,0,255);  // at函数定位位置,vec3b容器存放颜色
}
4. 图像的裁剪,注意,Mat类的操作也是对原始数据的引用
Mat img = imread("../assets/itheima.jpg",IMREAD_COLOR);
// 定义要截取的矩形框
Rect rect(100,50,200,200);
// 这样即可完成截取
Mat roi = img(rect);
5. 直方图获取及绘制,注意,这里的原点是图像的左上角位置,并非左下角
//
// Created by itheima on 6/12/19.
//
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(){
    // 读取图片
    Mat img = imread("../assets/lena.jpg",IMREAD_COLOR);
    imshow("src",img);
    // 单通道处理数据
    vector<Mat> bgr_channels;
    // 颜色分割
    split(img,bgr_channels);

    int histSize=256;
    float range[] = {0,256};
    const float * histRange = {range};
    // 用于说明bin宽度是否相等
//    bool uniform=true;
    // 当计算多通道直方图的时候,是否进行累加
//    bool accumulate=false;

    Mat b_hist,g_hist,r_hist;
    calcHist(&bgr_channels[0],1,0,Mat(),b_hist,1,&histSize,&histRange);
    calcHist(&bgr_channels[1],1,0,Mat(),g_hist,1,&histSize,&histRange);
    calcHist(&bgr_channels[2],1,0,Mat(),r_hist,1,&histSize,&histRange);

    int histsize = 256;

    // 创建一个灰色图像
    int hist_w = 512;
    int hist_h = 400;
    int bin_w = cvRound(512.0/histSize);
	//将直方图绘制到512*400大小的图像上去,要进行一定的缩放,需要进行归一化
    //进行归一化处理       最小值   最大值  模式
    normalize(b_hist,b_hist,0,hist_h,NORM_MINMAX);
    cout<<"归一化之后:"<<b_hist<<endl;

    Mat histImage(hist_h,hist_w,CV_8UC3,Scalar(0,0,0));
    // 绘制图像  这里只绘制了一个通道的直方图
    // 绘制直方图值时候,为更好的观看,做一点偏移
    // 注意,这里的原点是图像的左上角位置,并非左下角
    for(int i=0;i<histsize;i++){
        line(histImage,Point(bin_w*i,hist_h),Point(bin_w*i,hist_h-b_hist.at<float>(i-1)),Scalar(255,0,0),2,LINE_AA);
    }

    imshow("histgrom",histImage);
    waitKey(0);
    destroyAllWindows();
}
6. 直方图均衡化
#include <iostream>
#include <opencv2/opencv.hpp>


using namespace std;
using namespace cv;


int main() {
    Mat img = imread("../assets/itheima.jpg", IMREAD_COLOR);

    //将图像转成灰度图像
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    imshow("gray",gray);
    // 计算直方图
    Mat hist;
    int histSize = 256;
    float range[] = {0, 255.0};
    const float *histRange[] = {range};
    calcHist(&gray, 1, 0, Mat(), hist, 1, &histSize, histRange);

    // 计算直方图的概率
    Mat ratios = hist / (img.rows * img.cols);
    float sum1 = 0;
    // 计算直方图的累加概率
    for (int i = 0; i < ratios.rows; i++) {
        sum1 += ratios.at<float>(i);
        ratios.at<float>(i) = sum1;
    }
    cout<<ratios<<endl;

    Mat dst(gray.rows, gray.cols, CV_8UC1);
    // 对原图像进行处理
    for (int row = 0; row < img.rows; ++row) {
        for (int col = 0; col < img.cols; ++col) {
            // 获取每个位置的灰度值
            int color = gray.at<uint8_t>(row, col);
            // 根据颜色值从累计概率中获取累计概率
            float ratio = ratios.at<float>(color);
            // 计算新的颜色值
            color = cvRound(255 * ratio);
            // 填充到原图中
            dst.at<uchar>(row, col) = color;
        }
    }
    imshow("dst", dst);

    waitKey(0);
    destroyAllWindows();
    return 0;
}
7. 图像的卷积和滤波,注意Mat初始化方法
// 定义卷积核
    Mat kernel = (Mat_<char>(3,3)<<-1,-1,-1,
                                        -1,9,-1,
                                        -1,-1,-1);

    // 进行图像的卷积操作
    Mat dst;
    filter2D(img,dst,-1,kernel);
    //
    Mat gray;
    cvtColor(src_img,gray,COLOR_BGR2GRAY);
    GaussianBlur(gray,gray,Size(3,3),0);
    Laplacian(img,dst,-1,5); //-1表示输出类型和输入类型一致,5代表卷积核大小
    
    // sobel和sharr算子
    Mat xgray,ygray;
//    Sobel(gray,xgray,CV_16S,1,0);
//    Sobel(gray,ygray,CV_16S,0,1);
    Scharr(gray,xgray,CV_16S,1,0);
    Scharr(gray,ygray,CV_16S,0,1);
	//显示出问题时,若是由数据类型引起,可使用以下函数
	//功能是  缩放,计算绝对值,然后将结果转换为8位。
	convertScaleAbs(xgray,xgray);
	convertScaleAbs(ygray,ygray);
	add(xgray,ygray,result);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值