cxnet
发表于 2024-12-7 11:26:05
FishC 发表于 2024-12-7 11:22
To achieve a halftone effect with specific angles for the dot grid, like 15°, 45°, 75°, or 90 ...
bitwise_and(pattern, mask, dstRoi);
这一行代码报错
FishC
发表于 2024-12-7 11:27:27
cxnet 发表于 2024-12-07 11:26
bitwise_and(pattern, mask, dstRoi);
这一行代码报 ...
在使用`bitwise_and`函数时,确保`pattern`和`mask`有相同的尺寸和相同的类型(数据类型)。如果其中一个是一个小图案,需要在应用前调整为与目标区域大小(`dstRoi`)相同。
以下是确保`pattern`和`mask`具有相同尺寸和类型的方法,只需要在代码中做一些调整:
1. **创建标准化区域的掩码**:确保你的掩码每次应用时与`pattern`大小和位置对准。
2. **调整模式尺寸**:如果`pattern`尺寸与处理区域不同,考虑使用`resize`或者复制多个模式单位以覆盖整个区域。
以下是如何修复错误的一种方法:
#include <opencv2/opencv.hpp>
using namespace cv;
// Function to create a halftone pattern
void createHalftonePattern(Mat &pattern, int dotSpacing, double angle) {
int size = dotSpacing * 2; // Ensure pattern can rotate
pattern = Mat(size, size, CV_8UC1, Scalar(0));
Point center(size / 2, size / 2);
Mat rotationMatrix = getRotationMatrix2D(center, angle, 1);
// Create initial pattern with a circle
Mat tempPattern = Mat::zeros(size, size, CV_8UC1);
circle(tempPattern, center, dotSpacing / 2, Scalar(255), FILLED);
// Apply rotation to the pattern
warpAffine(tempPattern, pattern, rotationMatrix, pattern.size());
}
// Function to apply the halftone effect
void applyHalftonePattern(const Mat &src, Mat &dst, int dotSpacing, double angle) {
Mat pattern;
createHalftonePattern(pattern, dotSpacing, angle);
dst = src.clone();
for (int y = 0; y < src.rows; y += dotSpacing) {
for (int x = 0; x < src.cols; x += dotSpacing) {
Rect roi(x, y, dotSpacing, dotSpacing);
if (x + dotSpacing > src.cols || y + dotSpacing > src.rows)
continue;
// Extract the ROI from the source
Mat srcRoi = src(roi);
// Create a mask from the ROI
Mat mask;
threshold(srcRoi, mask, 128, 255, THRESH_BINARY);
// Copy the pattern to the same size as the ROI
Mat fullPattern;
pattern(Rect(0, 0, mask.cols, mask.rows)).copyTo(fullPattern);
// Use bitwise_and to extract the components
Mat dstRoi = dst(roi);
bitwise_and(fullPattern, mask, dstRoi);
}
}
}
int main() {
Mat img = imread("your_image_path.jpg", IMREAD_GRAYSCALE);
if (img.empty()) {
std::cerr << "Error: Cannot load image\n";
return -1;
}
Mat halftoneImg;
applyHalftonePattern(img, halftoneImg, 10, 45); // Example with dot size 10 and angle 45
imshow("Halftone Image", halftoneImg);
waitKey(0);
return 0;
}
**关键点:**
- **ROI和模式对齐**:确保模式(`pattern`)在每个处理区域(`roi`)都是相同的大小。
- **分区和填充**:通过复制并使用正确的索引调整单个图案。
- **适配边界**:如果需要,确保你处理的区域不会超出图像边界。
使用以上修正确保模式在整个应用过程中对齐和适配目标区域的大小。调试过程中可以检查每次处理中的矩阵类型和大小确保兼容。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
cxnet
发表于 2024-12-7 11:33:45
FishC 发表于 2024-12-6 15:01
要实现这种效果,可以在绘制圆形网点时,先检查网点周围的像素,确保在靠近白色区域的1像素灰色不绘制 ...
在这段代码的基础上设置上下左右四个半色调网点组成的角度为45度或者75度或者15度,切记是四个网点排列的角度并非1个网点旋转角度
FishC
发表于 2024-12-7 11:34:17
cxnet 发表于 2024-12-07 11:33
在这段代码的基础上设置上下左右四个半色调网点组成的 ...
要使半色调网点的排列达到特定的角度,比如45度、75度或15度,需要相应调整网点的排列方式。要实现这种效果,可以通过使用旋转后的网格或调整网点的排列间隔来达到所需的效果。这里是一个通过调整网点间距和布置来实现的思路:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
// 生成并返回一个旋转的半色调图案
void createHalftonePattern(Mat &pattern, int dotRadius, double angle) {
int size = dotRadius * 2; // 图案大小必须充足以旋转
pattern = Mat::zeros(size * 10, size * 10, CV_8UC1); // 创建一个足够大的图案矩阵
// 用于计算旋转的点中心和旋转矩阵
Point center(size, size);
Mat rotationMatrix = getRotationMatrix2D(center, angle, 1);
Mat tempPattern = Mat::zeros(size, size, CV_8UC1);
circle(tempPattern, center, dotRadius, Scalar(255), FILLED);
// 把圆点阵列用于跨越较大区域
for (int y = 0; y < pattern.rows; y += size) {
for (int x = 0; x < pattern.cols; x += size) {
Mat roi = pattern(Rect(x, y, size, size));
tempPattern.copyTo(roi);
}
}
// 对大的图案应用旋转
warpAffine(pattern, pattern, rotationMatrix, pattern.size());
}
// 应用半色调效果
void applyHalftonePattern(const Mat &src, Mat &dst, int dotRadius, double angle) {
Mat pattern;
createHalftonePattern(pattern, dotRadius, angle);
dst = src.clone();
for (int y = 0; y < src.rows; y += pattern.rows) {
for (int x = 0; x < src.cols; x += pattern.cols) {
Rect roi(x, y, pattern.cols, pattern.rows);
// 检查是否超过边界
if (x + pattern.cols > src.cols || y + pattern.rows > src.rows)
continue;
// 从源提取ROI
Mat srcRoi = src(roi);
// 创建一个小于128为黑的掩码用于对原始图像进行阈值化处理
Mat mask;
threshold(srcRoi, mask, 128, 255, THRESH_BINARY_INV);
// 复制图案以适应ROI的大小
Mat fullPattern;
pattern(Rect(0, 0, mask.cols, mask.rows)).copyTo(fullPattern);
// 使用bitwise_and提取组件
Mat dstRoi = dst(roi);
fullPattern.copyTo(dstRoi, mask);
}
}
}
int main() {
Mat img = imread("your_image_path.jpg", IMREAD_GRAYSCALE);
if (img.empty()) {
std::cerr << "Error: Cannot load image\n";
return -1;
}
Mat halftoneImg;
applyHalftonePattern(img, halftoneImg, 5, 45); // 调整dotRadius和angle以获得不同效果
imshow("Halftone Image", halftoneImg);
waitKey(0);
return 0;
}
**关键点:**
1. **dotRadius**: 控制每个半色调网点的大小。
2. **angle**: 控制整个网点图案旋转的角度,以影响四个网点的排列角度而不是单个网点的相对于光轴的旋转。
3. **布局**: 网点在较大的图案网格上被旋转和应用,以此影响网点布局形成网格的角度。
使用这个代码可以尝试设定`angle`为不同角度来观察网点排列的改变。调整`dotRadius`以匹配特定的像素密度根据你的需要。 这个方法准备了一个旋转后的网格用于实现半色调效果并尝试控制网点排列角度。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。