证件照换底色
蓝色换红色效果不错,其他的不行
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 }