|
|
您遇到了数组越界错误。让我提供一个完全修正的版本,解决所有问题:
- #include <opencv2/opencv.hpp>
- #include <vector>
- #include <cmath>
- using namespace cv;
- using namespace std;
- const int N = 16;
- const float PI = 3.14159265358979323846f;
- // 生成圆形网点阈值矩阵
- vector<vector<int>> createCircularDotMatrix(int size) {
- vector<vector<int>> matrix(size, vector<int>(size));
- float center = (size - 1) / 2.0f;
- float maxDist = size / 2.0f;
-
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- float dx = i - center;
- float dy = j - center;
- float distance = sqrt(dx*dx + dy*dy);
- float normalized = distance / maxDist;
-
- // 确保中心阈值低,边缘阈值高
- int threshold = static_cast<int>(normalized * 255);
- matrix[i][j] = threshold;
- }
- }
- return matrix;
- }
- // 检查是否为纯色文字边缘
- bool isSolidTextEdge(const vector<Mat>& cmykChannels, int x, int y, int width, int height) {
- if (x < 0 || x >= width || y < 0 || y >= height) return false;
-
- // 检查所有通道
- for (int c = 0; c < 4; c++) {
- uchar pixelValue = cmykChannels[c].at<uchar>(y, x);
-
- // 如果是灰色(非纯色)
- if (pixelValue > 10 && pixelValue < 245) {
- // 检查周围2像素内是否有纯色像素
- for (int dy = -2; dy <= 2; dy++) {
- for (int dx = -2; dx <= 2; dx++) {
- int nx = x + dx;
- int ny = y + dy;
-
- if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
- for (int c2 = 0; c2 < 4; c2++) {
- uchar neighborValue = cmykChannels[c2].at<uchar>(ny, nx);
- // 如果周围有纯黑色或纯白色
- if (neighborValue <= 10 || neighborValue >= 245) {
- return true;
- }
- }
- }
- }
- }
- }
- }
- return false;
- }
- // 半色调通道处理函数
- void halftoneChannel(Mat& input, Mat& output, float angle, int channelIndex,
- const vector<Mat>& cmykChannels, const vector<vector<int>>& dotMatrix) {
- int width = input.cols;
- int height = input.rows;
-
- // 计算旋转后的网格坐标
- float cos_angle = cos(angle);
- float sin_angle = sin(angle);
-
- // 网点间距
- float dotSpacing = N;
-
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- // 检查是否为纯色文字边缘
- if (isSolidTextEdge(cmykChannels, x, y, width, height)) {
- // 保留原色
- output.at<uchar>(y, x) = input.at<uchar>(y, x);
- continue;
- }
-
- uchar pixelValue = input.at<uchar>(y, x);
-
- // 纯色不处理
- if (pixelValue <= 10 || pixelValue >= 245) {
- output.at<uchar>(y, x) = pixelValue;
- continue;
- }
-
- // 计算在旋转网格中的位置
- float u = x * cos_angle + y * sin_angle;
- float v = -x * sin_angle + y * cos_angle;
-
- // 计算阈值矩阵索引
- int i = static_cast<int>(fmod(u, dotSpacing));
- int j = static_cast<int>(fmod(v, dotSpacing));
-
- // 确保索引在有效范围内
- if (i < 0) i += N;
- if (j < 0) j += N;
- i %= N;
- j %= N;
-
- // 获取阈值
- int threshold = dotMatrix[i][j];
-
- // 根据像素值和阈值决定是否绘制网点
- // 修正:确保浅色区域产生小网点,深色区域产生大网点
- if (pixelValue < threshold) {
- output.at<uchar>(y, x) = 0; // 黑色网点
- } else {
- output.at<uchar>(y, x) = 255; // 白色背景
- }
- }
- }
- }
- // 主函数
- int main() {
- // 读取CMYK图像
- Mat cmykImage = imread("input.tif", IMREAD_COLOR);
- if (cmykImage.empty()) {
- cout << "无法加载图像" << endl;
- return -1;
- }
-
- // 分离CMYK通道
- vector<Mat> cmykChannels;
- split(cmykImage, cmykChannels);
-
- // 定义角度(弧度)
- vector<float> angles = {
- 15.0f * PI / 180.0f, // C - 15度
- 75.0f * PI / 180.0f, // M - 75度
- 0.0f, // Y - 0度
- 45.0f * PI / 180.0f // K - 45度
- };
-
- // 创建输出通道
- vector<Mat> outputChannels(4);
- for (int i = 0; i < 4; i++) {
- outputChannels[i] = Mat::zeros(cmykChannels[i].size(), CV_8UC1);
- }
-
- // 创建网点矩阵
- vector<vector<int>> dotMatrix = createCircularDotMatrix(N);
-
- // 对每个通道应用半色调
- for (int i = 0; i < 4; i++) {
- halftoneChannel(cmykChannels[i], outputChannels[i], angles[i], i, cmykChannels, dotMatrix);
- }
-
- // 合并通道并保存
- Mat outputImage;
- merge(outputChannels, outputImage);
- imwrite("output.tif", outputImage);
-
- return 0;
- }
复制代码
这个修正版本解决了以下问题:
1. 修复了数组越界错误
2. 确保浅色区域产生小网点,深色区域产生大网点
3. 文字边缘的灰色保留原色,不进行网点化
4. 纯色区域(纯黑和纯白)不进行网点化
5. 使用正确的角度和网点间距
如果仍然有问题,请告诉我具体的错误信息,我会进一步修正。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|