zoukankan      html  css  js  c++  java
  • OpenCV学习(3)--证件照换底色、线性混合运算、增强图像对比度示例

    证件照换底色

    蓝色换红色效果不错,其他的不行

     1 // 照片换底色
     2 // 蓝色换为红色
     3 void red2Blue(cv::Mat& image, cv::Mat& rgbImage) {
     4     cv::Mat roi = image(cv::Rect(20, 20, 20, 20));  // cv::Rect() 参数表示矩形左上角和长宽信息
     5     cv::Mat hsvImage;
     6     cv::cvtColor(image, hsvImage, CV_BGR2HSV);  // 将图像转化为HSV颜色空间
     7     // 分离HSV空间 v[0]为H色调  v[1]为S饱和度  v[2]为v灰度
     8     vector<cv::Mat> v;
     9     cv::split(hsvImage, v);  // 多通道图像的分离
    10     cv::Mat roiH = v[0](cv::Rect(20, 20, 20, 20));
    11     cv::Mat roiS = v[1](cv::Rect(20, 20, 20, 20));
    12     int sumH = 0;
    13     int sumS = 0;
    14     int avgH, avgS;   // 蓝底的平均色调和平均饱和度
    15 
    16     // 取一块蓝色背景 计算出他们的平均色调和平均饱和度
    17     for (int i = 0; i < 20; i++) {
    18         for (int j = 0; j < 20; j++) {
    19             sumH = int(roiH.at<uchar>(j, i)) + sumH;
    20             sumS = int(roiS.at<uchar>(j, i)) + sumS;
    21         }
    22     }
    23 
    24     avgH = sumH / 400;
    25     avgS = sumS / 400;
    26 
    27     // 便利整个图像
    28     int rows = hsvImage.rows;
    29     int cols = hsvImage.cols;
    30     int step = 10;
    31 
    32     for (int j = 0; j < rows; j++) {
    33         for (int i = 0; i < cols; i++) {
    34             // 以H和S两个通道做阈值分割 把蓝色替换成红色
    35             if ((v[0].at<uchar>(j, i)) <= (avgH + 5) && (v[0].at<uchar>(j, i)) >= (avgH - 5)
    36                 && (v[1].at<uchar>(j, i)) <= (avgS + 40) && (v[1].at<uchar>(j, i)) >= (avgH - 40)) {
    37                 v[0].at<uchar>(j, i) = 0;
    38             }
    39         }
    40     }
    41 
    42     cv::Mat finImage;
    43     cv::merge(v, finImage);
    44     //cv::Mat rgbImage;
    45     cv::cvtColor(finImage, rgbImage, CV_HSV2BGR);  // 将图像转换回bgr空间
    46     cv::imwrite("whiteMyself.jpg", rgbImage);  // 写入硬盘
    47     cv::imshow("Res", rgbImage);
    48 
    49     cv::waitKey(0);
    50     return;
    51 }

    采用同样的方式,更改参数,使得红底变为白底,效果极差

     1 int main(void) {   // 证件照换底色 简单的将指定颜色换成另外一个颜色 不行 即直接通过bgr的值来识别颜色并转换效果不好
     2     cv::Mat src = cv::imread("myself.jpg", cv::IMREAD_COLOR);
     3     //cv::Mat res;
     4 
     5     if (src.empty()) {
     6         std::cout << "Failed!" << std::endl;
     7         return 1;
     8     }
     9 
    10     std::cout << "原图像!" << std::endl;
    11     cv::namedWindow("Src", cv::WINDOW_AUTOSIZE);
    12     cv::imshow("Src", src);
    13     cv::waitKey(0);
    14 
    15     for (int r = 0; r < src.rows; r++) {
    16         for (int c = 0; c < src.cols; c++) {
    17             if (src.ptr<uchar>(r, c)[0] == 255 && src.ptr<uchar>(r, c)[0] == 0 && src.ptr<uchar>(r, c)[0] == 0) {  // bgr 蓝色
    18                 // 蓝色替换成白色
    19                 src.ptr<uchar>(r, c)[0] = 255;
    20                 src.ptr<uchar>(r, c)[1] = 255;
    21                 src.ptr<uchar>(r, c)[2] = 255;
    22             }
    23         }
    24     }
    25 
    26     std::cout << "目标图像!" << std::endl;
    27     cv::namedWindow("Res", cv::WINDOW_AUTOSIZE);
    28     cv::imshow("Res", src);
    29 
    30     cv::waitKey(0);
    31     return 0;
    32 }

    两图像的线性混合运算

     1 int mixTwoPictureExample(cv::Mat src1, cv::Mat src2, cv::Mat dst) {
     2     double alpha = 0.7;
     3     double beta;
     4 
     5     src1 = cv::imread("angel.jpg", cv::IMREAD_COLOR);
     6     src2 = cv::imread("sky.jpg", cv::IMREAD_COLOR);
     7 
     8     cv::Mat roi1(src1, cv::Rect(0, 0, 1500, 800));
     9     cv::Mat roi2(src2, cv::Rect(0, 0, 1500, 800));
    10 
    11     if (src1.empty())
    12         std::cout << "Failed read angel!" << std::endl;
    13 
    14     if (src2.empty())
    15         std::cout << "Failed read sky!" << std::endl;
    16 
    17     beta = 1.0 - alpha;
    18 
    19     // g(x) = f1(x)*a + f2(x)*(1 - a)
    20     cv::addWeighted(roi1, alpha, roi2, beta, 0.0, dst);
    21     // 注意图片roi1 roi2大小要一样 alpha beta分别表示再组合后的图像中roi1 roi2所占的权重
    22     cv::namedWindow("Dst", cv::WINDOW_AUTOSIZE);
    23     cv::imshow("Dst", dst);
    24 
    25     cv::waitKey(0);
    26 
    27     return 0;
    28 }

    增加图像对比度

     1 int changeContrastAndBrightnessExample(void) {
     2     // 改变图像的对比度和亮度
     3     // g(r, c) = a*f(r, c) + b  a b越大图像越亮
     4     double alpha = 1.0;  // 范围1.0-3.0
     5     int beta = 50;        // 范围0-100
     6 
     7     cv::Mat image = cv::imread("angel.jpg", cv::IMREAD_COLOR);
     8     // 初始化一个与原图像大小类型相同的模板
     9     cv::Mat image2 = cv::Mat::zeros(image.size(), image.type());
    10 
    11     for (int r = 0; r < image.rows; r++) {
    12         for (int c = 0; c < image.cols; c++) {
    13             // 3通道值 bgr
    14             // cv::saturate_cast() 防溢出保护
    15             image2.at<cv::Vec3b>(r, c)[0] = cv::saturate_cast<uchar>(alpha * (image.at<cv::Vec3b>(r, c)[0]) + beta);
    16             image2.at<cv::Vec3b>(r, c)[1] = cv::saturate_cast<uchar>(alpha * (image.at<cv::Vec3b>(r, c)[1]) + beta);
    17             image2.at<cv::Vec3b>(r, c)[2] = cv::saturate_cast<uchar>(alpha * (image.at<cv::Vec3b>(r, c)[2]) + beta);
    18         }
    19     }
    20 
    21     // 另外可以使用cv::Mat::convertTo()实现相同效果
    22     // image.convertTo(image2, -1, alpha, beta);
    23 
    24     //cv::imshow("image", image);
    25     //cv::imshow("image2", image2);
    26 
    27     //cv::waitKey(0);
    28     return 0;
    29 }

    伽马矫正,放后面 

    1 void gammaCorrectionExample() {
    2 
    3 }
  • 相关阅读:
    [Hapi.js] Route parameters
    [Hapi.js] Logging with good and good-console
    [Hapi.js] Up and running
    [Unit Testing] Directive testing, require parent controller
    数学-盲点题:九个点用四条直线连起来
    汉语-词语-思维:思维方法
    汉语-词语-思维:思维方式
    汉语-词语:思维
    思考方式-数学-盲点题:盲点题
    摄像机-哈苏:哈苏
  • 原文地址:https://www.cnblogs.com/lnlin/p/13735724.html
Copyright © 2011-2022 走看看