【opencv】原图-波浪-噪声-灰度-真彩-减少颜色的迪丽热巴

该博客演示了使用OpenCV库进行图像处理的几种技术,包括图像锐化、创建波浪效果、添加盐噪声以及减少颜色。通过示例代码展示了如何实现这些操作,并提供了相应的图像展示结果。

#include "opencv2/imgcodecs/legacy/constants_c.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <random>
using namespace cv;
using namespace std;
void sharpen(const cv::Mat &image, cv::Mat &result)
{
    // 判断是否需要分配图像数据。如果需要,就分配
    result.create(image.size(), image.type());
    int nchannels = image.channels(); // 获得通道数
    // 处理所有行(除了第一行和最后一行)
    for (int j = 1; j < image.rows - 1; j++)
    {
        const uchar *previous = image.ptr<const uchar>(j - 1); // 上一行
        const uchar *current = image.ptr<const uchar>(j);      // 当前行
        const uchar *next = image.ptr<const uchar>(j + 1);     // 下一行
        uchar *output = result.ptr<uchar>(j);                  // 输出行
        for (int i = nchannels; i < (image.cols - 1) * nchannels; i++)
        {
            // 应用锐化算子
            *output++ = cv::saturate_cast<uchar>(
                5.3 * current[i] - current[i - nchannels] -
                current[i + nchannels] - previous[i] - next[i]);
        }
    }
    // 把未处理的像素设为 0
    result.row(0).setTo(cv::Scalar(0));
    result.row(result.rows - 1).setTo(cv::Scalar(0));
    result.col(0).setTo(cv::Scalar(0));
    result.col(result.cols - 1).setTo(cv::Scalar(0));
}

void salt(cv::Mat image, int n)
{
    // C++11 的随机数生成器
    std::default_random_engine generator;
    std::uniform_int_distribution<int>
        randomRow(0, image.rows - 1);
    std::uniform_int_distribution<int>
        randomCol(0, image.cols - 1);
    int i, j;
    for (int k = 0; k < n; k++)
    {
        // 随机生成图形位置
        i = randomCol(generator);
        j = randomRow(generator);
        if (image.type() == CV_8UC1)
        { // 灰度图像
            // 单通道 8 位图像
            image.at<uchar>(j, i) = 255;
        }
        else if (image.type() == CV_8UC3)
        { // 彩色图像
            // 3 通道图像
            image.at<cv::Vec3b>(j, i)[0] = 255;
            image.at<cv::Vec3b>(j, i)[1] = 255;
            image.at<cv::Vec3b>(j, i)[2] = 255;
        }
    }
}

void wave(const cv::Mat &image, cv::Mat &result)
{
    // 映射参数
    cv::Mat srcX(image.rows, image.cols, CV_32F);
    cv::Mat srcY(image.rows, image.cols, CV_32F);
    // 创建映射参数
    for (int i = 0; i < image.rows; i++)
    {
        for (int j = 0; j < image.cols; j++)
        {
            // (i,j)像素的新位置
            srcX.at<float>(i, j) = j; // 保持在同一列
            // 原来在第 i 行的像素,现在根据一个正弦曲线移动
            srcY.at<float>(i, j) = i + 7 * sin(j / 10.0);
        }
    }
    // 应用映射参数
    cv::remap(image,             // 源图像
              result,            // 目标图像
              srcX,              // x 映射
              srcY,              // y 映射
              cv::INTER_LINEAR); // 填补方法
}
void colorReduce(cv::Mat image, int div = 64)
{
    int nl = image.rows; // 行数
    // 每行的元素数量
    int nc = image.cols * image.channels();
    for (int j = 0; j < nl; j++)
    {
        // 取得行j的地址
        uchar *data = image.ptr<uchar>(j);
        for (int i = 0; i < nc; i++)
        {
            // 处理每个像素 ---------------------
            data[i] = data[i] / div * div + div / 2;
            // 像素处理结束 ----------------
        }
    }
}
int main()
{
    //Mat src = imread("./1.png", IMREAD_GRAYSCALE);
    Mat src = imread("./dlrb.png");
    Mat src2 = imread("./dlrb.png");
    Mat src3 = imread("./dlrb.png");
    Mat src4 = imread("./dlrb.png");
    Mat src5 = imread("./dlrb.png");
    Mat src6;
    Mat src7;
    Mat src8;
    if (src.empty())
    {
        cout << "Did not find the image" << endl;
        return 0;
    }
    sharpen(src, src2);
    wave(src, src3);
    salt(src4, 3000);
    colorReduce(src5, 64);
    src6 = cv::imread("dlrb.png", CV_LOAD_IMAGE_GRAYSCALE);
    cvtColor(src, src7, COLOR_BGR2HSV);  // 真彩色
    cvtColor(src, src8, COLOR_BGR2GRAY); // 灰色

    imshow("原图", src);
    imshow("锐化之后的图", src2);
    imshow("波浪后的图", src3);
    imshow("添加噪声以后的图", src4);
    imshow("减少颜色以后的图", src5);
    imshow("灰度图", src6);
    imshow("真彩图", src7);
    // imshow("灰度图", src8);
    waitKey(0);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值