cv08_cleanLight.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <opencv2/opencv.hpp>
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #pragma comment(lib, "opencv_world4100.lib")
  6. using namespace cv;
  7. using namespace std;
  8. void removeShadow(const Mat &src, Mat &dst);
  9. void resizeToFitScreen(const Mat &src, Mat &resized, int screenWidth, int screenHeight);
  10. void applyLevels(Mat &img, int black, int white);
  11. void readOrWriteConfig(const char *filename, double *alpha, int *beta, int *black, int *white);
  12. int main(int argc, char *argv[])
  13. {
  14. if (argc < 2) {
  15. puts("文稿一键美白App By 蘭雅 捞鱼吧 bbs.lyvba.com\n");
  16. puts("Usage: cleanLight.exe image [new_image]\n");
  17. int i = getchar();
  18. return 8;
  19. }
  20. // 读取输入图像
  21. Mat src = imread(argv[1]);
  22. if (src.empty()) {
  23. puts("Error: Could not open or find the image.\n");
  24. return -1;
  25. }
  26. Mat result;
  27. removeShadow(src, result);
  28. // 设置对比度和亮度参数
  29. double alpha = 1.2; // 对比度因子
  30. int beta = 8; // 亮度偏移
  31. int black = 30; // 色阶黑阈值
  32. int white = 235; // 色阶白阈值
  33. const char *inifile = "cleanLight.ini";
  34. readOrWriteConfig(inifile, &alpha, &beta, &black, &white);
  35. convertScaleAbs(result, result, alpha, beta);
  36. // 应用色阶调整
  37. applyLevels(result, black, white);
  38. // 7. 将结果保存为图像
  39. char filename[256] = "removeShadow_color.png";
  40. if (argc == 3) strcpy(filename, argv[2]);
  41. imwrite(filename, result);
  42. // 屏幕分辨率
  43. int screenWidth = 1920;
  44. int screenHeight = 1080;
  45. // 调整图像大小
  46. Mat resizedSrc, resizedResult;
  47. resizeToFitScreen(src, resizedSrc, screenWidth / 2, screenHeight);
  48. resizeToFitScreen(result, resizedResult, screenWidth / 2, screenHeight);
  49. // 拼接图像
  50. Mat combined;
  51. hconcat(resizedSrc, resizedResult, combined);
  52. // 显示结果
  53. imshow("原图和文稿一键美白图像 By 蘭雅", combined);
  54. waitKey(50);
  55. MessageBoxA(NULL,"文稿一键美白完成,感谢您的试用!\n原创软件->捞鱼吧 bbs.lyvba.com\n对比度和色阶微调请修改 cleanLight.ini\n",
  56. "文稿一键美白App By 蘭雅", MB_ICONINFORMATION);
  57. return 0;
  58. }
  59. void readOrWriteConfig(const char *filename, double *alpha, int *beta, int *black, int *white)
  60. {
  61. // 尝试打开文件
  62. FILE *file = fopen(filename, "r");
  63. if (file) {
  64. // 如果文件存在,从中读取变量
  65. fscanf(file, "%lf %d %d %d", alpha, beta, black, white);
  66. fclose(file);
  67. printf("读取成功: alpha = %.2f, beta = %d\n色阶黑白阈值: black = %d, white = %d\n", *alpha, *beta, *black, *white);
  68. }
  69. else {
  70. // 如果文件不存在,创建文件并写入变量
  71. *alpha = 1.2;
  72. *beta = 8;
  73. *black = 30;
  74. *white = 235;
  75. file = fopen(filename, "w");
  76. if (file) {
  77. fprintf(file, "%.2f %d %d %d\n", *alpha, *beta, *black, *white);
  78. fclose(file);
  79. printf("文件未找到,已创建并写入: alpha = %.2f, beta = %d\n色阶黑白阈值: black = %d, white = %d\n", *alpha, *beta, *black, *white);
  80. }
  81. else {
  82. perror("无法创建文件");
  83. exit(EXIT_FAILURE);
  84. }
  85. }
  86. }
  87. void removeShadow(const Mat &src, Mat &dst)
  88. {
  89. // 1. 将图像转换为 HSV 色彩空间
  90. Mat hsv;
  91. cvtColor(src, hsv, COLOR_BGR2HSV);
  92. // 分离通道
  93. vector<Mat> hsvChannels;
  94. split(hsv, hsvChannels);
  95. // 2. 对 V 通道进行处理
  96. Mat vChannel = hsvChannels[2];
  97. Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
  98. int iteration = 9;
  99. // 3. 膨胀和腐蚀操作
  100. Mat dilateMat;
  101. morphologyEx(vChannel, dilateMat, MORPH_DILATE, element, Point(-1, -1), iteration);
  102. Mat erodeMat;
  103. morphologyEx(dilateMat, erodeMat, MORPH_ERODE, element, Point(-1, -1), iteration);
  104. // 4. 计算去阴影效果
  105. Mat calcMat = ~(erodeMat - vChannel);
  106. normalize(calcMat, calcMat, 0, 255, NORM_MINMAX);
  107. // 5. 将处理后的 V 通道与原始 H 和 S 通道合并
  108. hsvChannels[2] = calcMat;
  109. merge(hsvChannels, hsv);
  110. // 6. 将 HSV 转换回 BGR 色彩空间
  111. cvtColor(hsv, dst, COLOR_HSV2BGR);
  112. }
  113. void resizeToFitScreen(const Mat &src, Mat &resized, int screenWidth, int screenHeight)
  114. {
  115. Size srcSize = src.size();
  116. int newWidth, newHeight;
  117. // 检测是宽大还是高大
  118. if (srcSize.width > srcSize.height) {
  119. // 按屏幕宽等比缩放
  120. newWidth = screenWidth;
  121. newHeight = srcSize.height * screenWidth / srcSize.width;
  122. }
  123. else {
  124. // 按屏幕高等比缩放
  125. newHeight = screenHeight;
  126. newWidth = srcSize.width * screenHeight / srcSize.height;
  127. }
  128. resize(src, resized, Size(newWidth, newHeight));
  129. }
  130. void applyLevels(Mat &img, int black, int white)
  131. {
  132. // 计算缩放因子
  133. double scale = 255.0 / (white - black);
  134. img.convertTo(img, CV_8U, scale, -black * scale);
  135. }