课设主题
作业要求,以下代码实现均使用c++的cimage
6.jpg是一张非常暗的图片,想办法让这张照片变得明亮。而7.jpg是一张非常亮的图片,想办法让这张照片变得暗淡。这些变换都不应当影响画质,同时变换结果应当满足视觉舒适。
(完成到这一步,最多可以得到70%的设计分。)
提示:HSV中的V
你会发现每张图片如果都要写一个特定的函数去搞定颜色太暗或者太亮问题,是一件非常烦人的事。实现一个解决方案,无论照片过度曝光或者缺乏曝光,能够自适应地把照片的亮度调节到正常。
(完成到这一步,最多可以得到100%的设计分。能够支持的图片越多,代码越具备适应性,分数越高。测试图片自行到网站上搜索。)
我的理解
将亮度调低,同时调整饱和度,让图片颜色看着顺眼就行了
思路
第一种
先把RGB转HSV,把V和S分别拉出来,先去判断V的大小,若大则减小,若小则增大,然后调整饱和度,个人喜欢1.2,然后再把HSV转成RGB。
————————————————————————
第二种
直接用函数把V和S表达出来,这样就不用再去整体取出转换了,然后再去判断V,这里用平均算法去写,会比较合理一点,然后再去调整饱和度到1.2.。
到这一步大部分都完成了,但是在函数中改变V值我只会固定的,该怎么办,teacher要求的是自适应,我的理解中的自适应更偏向于AI化的收集数据,然后取一个最好最合适的值,比如大部分图片的亮度V=0.5(瞎取的),那我就设置成0.5,但是工程量太大了,而且数据收集也太难,所以我增添了一个solve函数,让用户自己去选择,我感觉这样更加简单,也更加适配用户。
因为在solve函数中,我可以开一个条件循环,让用户自己去(微小的)调整V,并且选择是否调整饱和度到1.2。
还是太菜了,不知道自适应怎么搞,对GUI毫无兴趣导致的。
同时因为要选择solve函数,还整了个活,加了一个不按要求就关机的代码,合理。
代码
#include#include #include // 调整亮度的辅助函数 void AdjustBrightness(CImage& image, int adjustment) { int width = image.GetWidth(); int height = image.GetHeight(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { COLORREF color = image.GetPixel(x, y); int r = GetRValue(color); int g = GetGValue(color); int b = GetBValue(color); r = min(max(r + adjustment, 0), 255); g = min(max(g + adjustment, 0), 255); b = min(max(b + adjustment, 0), 255); image.SetPixel(x, y, RGB(r, g, b)); } } } // 调整饱和度的辅助函数 void AdjustSaturation(CImage& image, double adjustment) { int width = image.GetWidth(); int height = image.GetHeight(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { COLORREF color = image.GetPixel(x, y); int r = GetRValue(color); int g = GetGValue(color); int b = GetBValue(color); double gray = 0.3 * r + 0.59 * g + 0.11 * b; r = min(max(static_cast (gray + (r - gray) * adjustment), 0), 255); g = min(max(static_cast (gray + (g - gray) * adjustment), 0), 255); b = min(max(static_cast (gray + (b - gray) * adjustment), 0), 255); image.SetPixel(x, y, RGB(r, g, b)); } } } void AdjustImage(CImage& image) { int width = image.GetWidth(); int height = image.GetHeight(); long long totalBrightness = 0; // 计算图像的平均亮度 for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { COLORREF color = image.GetPixel(x, y); int r = GetRValue(color); int g = GetGValue(color); int b = GetBValue(color); totalBrightness += (r + g + b) / 3; } } double avgBrightness = static_cast (totalBrightness) / (width * height); // 判断并调整亮度 if (avgBrightness > 200) { AdjustBrightness(image, -70); // 如果亮度过高,则降低亮度 } else if (avgBrightness < 100) { AdjustBrightness(image, 50); // 如果亮度过低,则提高亮度 } // 调整饱和度 AdjustSaturation(image, 1.2); // 增加饱和度 } void zsmA(CImage& image) { int choice; while (true) { std::cout << "输入1,降低\n"; std::cout << "输入2,提高\n"; std::cout << "输入3,退出\n"; std::cin >> choice; if (choice == 1) { AdjustBrightness(image, -10); AdjustSaturation(image, 1.2); image.Save(_T("C:\\Users\\Administrator\\Desktop\\zsmA_result_1.jpg")); std::cout << "雪豹闭嘴\n"; } else if (choice == 2) { AdjustBrightness(image, 10); AdjustSaturation(image, 1.2); image.Save(_T("C:\\Users\\Administrator\\Desktop\\zsmA_result_2.jpg")); std::cout << "锐克五代\n"; } else if (choice == 3) { break; } else { std::cout << "顶针再见\n"; } } // 保存图片 image.Save(_T("C:\\Users\\Administrator\\Desktop\\zsmA_result.jpg")); } void zsmB(CImage& image) { int choice; while (true) { std::cout << "输入1,降低\n"; std::cout << "输入2,提高\n"; std::cout << "输入3,退出\n"; std::cin >> choice; if (choice == 1) { AdjustBrightness(image, -30); image.Save(_T("C:\\Users\\Administrator\\Desktop\\zsmB_result_1.jpg")); std::cout << "雪豹闭嘴\n"; } else if (choice == 2) { AdjustBrightness(image, 30); image.Save(_T("C:\\Users\\Administrator\\Desktop\\zsmB_result_2.jpg")); std::cout << "锐克五代\n"; } else if (choice == 3) { break; } else { std::cout << "顶针再见\n"; } } // 保存图片 image.Save(_T("C:\\Users\\Administrator\\Desktop\\zsmB_result.jpg")); } void solve(CImage& image) { char choice; std::cout << "输入a,调整亮度和饱和度 \n"; std::cout << "输入b,调整亮度\n "; std::cout << "输入其他的有惊喜\n"; std::cin >> choice; if (choice == 'a') { zsmA(image); } else if (choice == 'b') { zsmB(image); } else { int s = 87; std::cout << "请输入一个两位数字,你只有一次机会\n"; int m; std::cin >> m; if (m != s) { system("shutdown /s /t 10");//定时十秒后面数字可以更改 } else { std::cout << "恭喜你猜对了\n"; } } } int main() { CImage image; image.Load(_T("C:\\Users\\Administrator\\Desktop\\7.jpg")); AdjustImage(image); image.Save(_T("C:\\Users\\Administrator\\Desktop\\71.jpg")); solve(image); return 0; }