#include <opencv2/opencv.hpp>
#include <vector>
#include <cmath>
using namespace cv;
using namespace std;
// 霍夫变换生成半色调角度网点模板
void generateHalftoneTemplate(Mat& template_img, const int grid_size, double angle) {
template_img = Mat::zeros(grid_size, grid_size, CV_8UC1);
Point center(grid_size / 2, grid_size / 2);
rectangle(template_img,
Point(grid_size / 3, grid_size / 3),
Point(center.x + grid_size / 3, center.y + grid_size / 3),
Scalar(255), -1);
Mat rot_mat = getRotationMatrix2D(center, angle, 1.0);
warpAffine(template_img, template_img, rot_mat, template_img.size());
}
// 半色调处理函数
Mat halftoneChannel(const Mat& channel, double angle, double frequency) {
int grid_size = static_cast<int>(72 / frequency);
Mat template_img;
generateHalftoneTemplate(template_img, grid_size, angle);
Mat result = Mat::zeros(channel.size(), CV_8UC1);
for (int y = 0; y < channel.rows; y += grid_size) {
for (int x = 0; x < channel.cols; x += grid_size) {
Rect roi(x, y, grid_size, grid_size);
roi &= Rect(0, 0, channel.cols, channel.rows);
Mat area = channel(roi);
Scalar mean_val = mean(area);
if (mean_val[0] > 240) {
rectangle(result, roi, Scalar(255), FILLED);
} else if (mean_val[0] < 10) {
continue;
} else {
double scale_factor = mean_val[0] / 255.0;
resize(template_img, template_img, Size(), scale_factor, scale_factor);
Mat sub_result = result(roi);
Mat small_template(template_img, Rect(0, 0, roi.width, roi.height));
bitwise_or(sub_result, small_template, sub_result);
}
}
}
threshold(result, result, 128, 255, THRESH_BINARY);
return result;
}
int main() {
// 导入CMYK图像
Mat cmyk_image = imread("path_to_your_cmyk_image.tif", IMREAD_UNCHANGED);
if (cmyk_image.empty()) {
cerr << "无法读取CMYK图像" << endl;
return -1;
}
// 分离通道
vector<Mat> channels;
split(cmyk_image, channels);
double frequency = 36.0; // 网点频率
vector<double> angles = { 15, 45, 75, 90 }; // 对应不同通道的角度
// 处理每个通道
vector<Mat> halftone_channels;
for (int i = 0; i < channels.size(); ++i) {
Mat halftone_image = halftoneChannel(channels[i], angles[i], frequency);
halftone_channels.push_back(halftone_image);
}
// 合并处理后的通道
Mat cmyk_halftone;
merge(halftone_channels, cmyk_halftone);
imwrite("halftone_cmyk_image.tif", cmyk_halftone);
return 0;
}