|
| 1 | +//1. 图像旋转 |
| 2 | +Mat RotateImage(const Mat &img, int degree) { |
| 3 | + degree = -degree; //warpAffine默认的旋转方向是逆时针,所以加负号表示转化为顺时针 |
| 4 | + double angle = degree * CV_PI / 180.; //弧度 |
| 5 | + double a = sin(angle), b = cos(angle); |
| 6 | + int width = img.cols; |
| 7 | + int height = img.rows; |
| 8 | + int width_rotate = int(height * fabs(a) + width * fabs(b)); |
| 9 | + int height_rotate = int(width * fabs(a) + height * fabs(b)); |
| 10 | + float map[6]; |
| 11 | + Mat map_matrix = Mat(2, 3, CV_32F, map); |
| 12 | + //旋转中心 |
| 13 | + CvPoint2D32f center = cvPoint2D32f(width / 2, height / 2); |
| 14 | + CvMat map_matrix2 = map_matrix; |
| 15 | + cv2DRotationMatrix(center, degree, 1.0, &map_matrix2); |
| 16 | + //Adjust rotation center to dst's center, |
| 17 | + // otherwise you will get only part of the result |
| 18 | + map[2] += (width_rotate - width) / 2; |
| 19 | + map[5] += (height_rotate - height) / 2; |
| 20 | + Mat img_rotate; |
| 21 | + //对图像做仿射变换 |
| 22 | + warpAffine(img, img_rotate, map_matrix, Size(width_rotate, height_rotate), 1, 0, 0); |
| 23 | + return img_rotate; |
| 24 | +} |
| 25 | + |
| 26 | +//生成高斯分布随机数数列(Marsgglia和Bray在1964年提出) |
| 27 | +double generateGaussianNoise(double mu, double sigma) |
| 28 | +{ |
| 29 | + static double V1, V2, S; |
| 30 | + static int phase = 0; |
| 31 | + double X; |
| 32 | + double U1, U2; |
| 33 | + if (phase == 0) { |
| 34 | + do { |
| 35 | + U1 = (double)rand() / RAND_MAX; |
| 36 | + U2 = (double)rand() / RAND_MAX; |
| 37 | + V1 = 2 * U1 - 1; |
| 38 | + V2 = 2 * U2 - 1; |
| 39 | + S = V1 * V1 + V2 * V2; |
| 40 | + } while (S >= 1 || S == 0); |
| 41 | + X = V1 * sqrt(-2 * log(S) / S); |
| 42 | + }else{ |
| 43 | + X = V2 * sqrt(-2 * log(S) / S); |
| 44 | + } |
| 45 | + phase = 1 - phase; |
| 46 | + return mu + sigma * X; |
| 47 | +} |
| 48 | + |
| 49 | +//2. 添加高斯噪声(加性噪声) |
| 50 | +//k表示高斯噪声系数,k越大,高斯噪声系数越强 |
| 51 | +Mat AddGaussianNoise(const Mat &img, double mu, double sigma, int k) { |
| 52 | + Mat dst; |
| 53 | + dst.create(img.rows, img.cols, img.type()); |
| 54 | + for (int x = 0; x < img.rows; x++) { |
| 55 | + for (int y = 0; y < img.cols; y++) { |
| 56 | + double temp = img.at<uchar>(x, y) + k * generateGaussianNoise(mu, sigma); |
| 57 | + if (temp > 255) { |
| 58 | + temp = 255; |
| 59 | + } |
| 60 | + else if (temp < 0) { |
| 61 | + temp = 0; |
| 62 | + } |
| 63 | + dst.at<uchar>(x, y) = temp; |
| 64 | + } |
| 65 | + } |
| 66 | + return dst; |
| 67 | +} |
| 68 | + |
| 69 | +//3.添加椒盐噪声,椒盐噪声是根据图像信噪比,随机生成一些图像内的像素位置并随机对这些像素点赋值为0或255 |
| 70 | +// SNR等于0-1的浮点数,用来控制选取位置的多少 |
| 71 | +Mat AddSaltNoise(const Mat &img, double SNR) { |
| 72 | + Mat dst; |
| 73 | + dst.create(img.rows, img.cols, img.type()); |
| 74 | + int SP = img.rows * img.cols; |
| 75 | + int NP = SP*(1 - SNR); //获得需要添加椒盐噪声的像素个数 |
| 76 | + dst = img.clone(); |
| 77 | + for (int i = 0; i < NP; i++) { |
| 78 | + int x = (int)(rand()*1.0 / RAND_MAX * (double)img.rows); |
| 79 | + int y = (int)(rand()*1.0 / RAND_MAX * (double)img.cols); |
| 80 | + int r = rand() % 2; |
| 81 | + if (r) { |
| 82 | + dst.at<uchar>(x, y) = 0; |
| 83 | + } |
| 84 | + else { |
| 85 | + dst.at<uchar>(x, y) = 255; |
| 86 | + } |
| 87 | + } |
| 88 | + return dst; |
| 89 | +} |
| 90 | + |
| 91 | +//4. 调整图像饱和度(PhotoShop中的饱和度调节) |
| 92 | +//(1) 计算每个像素点三基色最小值和最大值 |
| 93 | +//(2) delta为2值之差/255,如果二值之差为0不操作 |
| 94 | +//(3)value为两值之和 |
| 95 | +//(4)RGB图像空间转化为HSL(H色调,S饱和度,L亮度) |
| 96 | +//L = value/2 |
| 97 | +//如果L<0.5,则S=delta/value |
| 98 | +//否则S=delta/(2-value) |
| 99 | +//Increment为饱和度,正值为增加饱和度,负值为降低饱和度,取值为(-1,1) |
| 100 | +//(5)根据不同的公式得到新的rgb值 |
| 101 | +Mat ChangeColor(const Mat &img, const float Increment) { |
| 102 | + Mat dst; |
| 103 | + Mat Img_out(img.size(), CV_32FC3); |
| 104 | + img.convertTo(Img_out, CV_32FC3); |
| 105 | + Mat Img_in(img.size(), CV_32FC3); |
| 106 | + img.convertTo(Img_in, CV_32FC3); |
| 107 | + //定义输入图像的迭代器 |
| 108 | + MatIterator_<Vec3f>inp_begin, inp_end; |
| 109 | + inp_begin = Img_in.begin<Vec3f>(); |
| 110 | + inp_end = Img_in.end<Vec3f>(); |
| 111 | + //定义输出图像的迭代器 |
| 112 | + MatIterator_<Vec3f>out_begin, out_end; |
| 113 | + out_begin = Img_out.begin<Vec3f>(); |
| 114 | + out_end = Img_out.end<Vec3f>(); |
| 115 | + float delta = 0; |
| 116 | + float minVal, maxVal, t1, t2, t3, L, S, alpha; |
| 117 | + for (; inp_begin != inp_end; inp_begin++, out_begin++) { |
| 118 | + t1 = (*inp_begin)[0]; |
| 119 | + t2 = (*inp_begin)[1]; |
| 120 | + t3 = (*inp_begin)[2]; |
| 121 | + |
| 122 | + minVal = std::min(std::min(t1, t2), t3); |
| 123 | + maxVal = std::max(std::max(t1, t2), t3); |
| 124 | + |
| 125 | + delta = (maxVal - minVal) / 255.0; |
| 126 | + L = 0.5 * (maxVal + minVal) / 255.0; |
| 127 | + S = std::max(0.5 * delta / L, 0.5 * delta / (1 - L)); |
| 128 | + if (Increment > 0) { |
| 129 | + alpha = max(S, 1 - Increment); |
| 130 | + alpha = 1.0 / alpha - 1; |
| 131 | + (*out_begin)[0] = (*inp_begin)[0] + ((*inp_begin)[0] - L*255.0) * alpha; |
| 132 | + (*out_begin)[1] = (*inp_begin)[1] + ((*inp_begin)[1] - L*255.0) * alpha; |
| 133 | + (*out_begin)[2] = (*inp_begin)[2] + ((*inp_begin)[2] - L*255.0) * alpha; |
| 134 | + } |
| 135 | + else { |
| 136 | + alpha = Increment; |
| 137 | + (*out_begin)[0] = L*255.0 + ((*inp_begin)[0] - L*255.0) * (1 + alpha); |
| 138 | + (*out_begin)[1] = L*255.0 + ((*inp_begin)[1] - L*255.0) * (1 + alpha); |
| 139 | + (*out_begin)[2] = L*255.0 + ((*inp_begin)[2] - L*255.0) * (1 + alpha); |
| 140 | + } |
| 141 | + } |
| 142 | + Img_out.convertTo(dst, CV_8UC3); |
| 143 | + return dst; |
| 144 | +} |
| 145 | + |
| 146 | +//5. 给图片增加老照片效果 |
| 147 | +Mat OldPicture(const Mat &src) { |
| 148 | + Mat Image_out(src.size(), CV_32FC3); |
| 149 | + src.convertTo(Image_out, CV_32FC3); |
| 150 | + Mat Image_2(src.size(), CV_32FC3); |
| 151 | + src.convertTo(Image_2, CV_32FC3); |
| 152 | + Mat r(src.rows, src.cols, CV_32FC1); |
| 153 | + Mat g(src.rows, src.cols, CV_32FC1); |
| 154 | + Mat b(src.rows, src.cols, CV_32FC1); |
| 155 | + Mat out[] = {b, g, r}; |
| 156 | + split(Image_2, out); |
| 157 | + Mat r_new(src.rows, src.cols, CV_32FC1); |
| 158 | + Mat g_new(src.rows, src.cols, CV_32FC1); |
| 159 | + Mat b_new(src.rows, src.cols, CV_32FC1); |
| 160 | + r_new = 0.393*r + 0.769*g + 0.189*b; |
| 161 | + g_new = 0.349*r + 0.686*g + 0.168*b; |
| 162 | + b_new = 0.272*r + 0.534*g + 0.131*b; |
| 163 | + Mat rgb[] = { b_new, g_new, r_new }; |
| 164 | + merge(rgb, 3, Image_out); |
| 165 | + Mat dstImg; |
| 166 | + Image_out.convertTo(dstImg, CV_8UC3); |
| 167 | + return dstImg; |
| 168 | +} |
| 169 | + |
0 commit comments