|
|
您遇到了数组越界错误。让我提供一个修正版本,确保所有数组访问都在有效范围内:
- #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);
-
- // 归一化距离到0-1范围
- float normalized = distance / maxDist;
-
- // 转换为阈值 (0-255),确保中心值小,边缘值大
- 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);
-
- // 如果是灰色像素 (1-99%)
- 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) {
- uchar neighborValue = cmykChannels[c].at<uchar>(ny, nx);
- // 如果邻居是纯色 (0%或100%)
- if (neighborValue <= 10 || neighborValue >= 245) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
- }
- // 半色调通道处理函数
- void halftoneChannel(Mat& input, Mat& output, float angle, int channelIndex,
- const vector<Mat>& allChannels, const vector<vector<int>>& dotMatrix) {
- int width = input.cols;
- int height = input.rows;
- int matrixSize = dotMatrix.size();
-
- float cos_angle = cos(angle);
- float sin_angle = sin(angle);
-
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- // 检查是否为纯色文字边缘
- if (isSolidTextEdge(allChannels, x, y, width, height)) {
- // 如果是边缘灰色,直接转为纯色
- uchar pixelValue = input.at<uchar>(y, x);
- output.at<uchar>(y, x) = (pixelValue > 127) ? 255 : 0;
- continue;
- }
-
- // 检查是否为纯色 (0%或100%)
- uchar pixelValue = input.at<uchar>(y, x);
- if (pixelValue <= 10 || pixelValue >= 245) {
- // 纯色直接保留
- output.at<uchar>(y, x) = (pixelValue > 127) ? 255 : 0;
- continue;
- }
-
- // 计算旋转后的坐标
- float u = x * cos_angle + y * sin_angle;
- float v = -x * sin_angle + y * cos_angle;
-
- // 确保索引在矩阵范围内
- int i = abs(static_cast<int>(fmod(u, matrixSize)));
- int j = abs(static_cast<int>(fmod(v, matrixSize)));
- i = i % matrixSize;
- j = j % matrixSize;
-
- // 获取阈值
- int threshold = dotMatrix[i][j];
-
- // 应用半色调
- if (pixelValue > threshold) {
- output.at<uchar>(y, x) = 255; // 白色
- } else {
- output.at<uchar>(y, x) = 0; // 黑色
- }
- }
- }
- }
- // 主转换函数
- void convertToHalftone(vector<Mat>& cmykChannels, vector<Mat>& outputChannels) {
- // 定义角度 (15°, 75°, 0°, 45°)
- vector<float> angles = {
- 15.0f * PI / 180.0f,
- 75.0f * PI / 180.0f,
- 0.0f,
- 45.0f * PI / 180.0f
- };
-
- // 创建圆形网点矩阵
- vector<vector<int>> dotMatrix = createCircularDotMatrix(N);
-
- // 处理每个通道
- for (int i = 0; i < 4; i++) {
- outputChannels[i] = Mat::zeros(cmykChannels[i].size(), CV_8UC1);
- halftoneChannel(cmykChannels[i], outputChannels[i], angles[i], i, cmykChannels, dotMatrix);
- }
- }
复制代码
主要修正:
1. 添加了边界检查,确保所有数组访问都在有效范围内
2. 使用 `%` 操作符确保矩阵索引不会越界
3. 使用 `abs()` 函数确保索引非负
4. 在 `isSolidTextEdge` 函数中添加了边界检查
5. 保持了圆形网点矩阵的正确生成逻辑
这个版本应该能够正常运行而不会出现数组越界错误。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|