|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在c++中我用下面代码可以在不旋转图片的情况下给灰色Mat图像转为圆形网点(旋转图像加网的情况下,图像旋转后会产生锯齿,所以不适合)。
但现在有2个问题
第一,所有颜色都是一样大的网点,实际上应该按照颜色深浅不同而生成不同大小的网点
第二,纯黑色(即95%以上颜色)不加网,请问应该怎样修改?
#include <opencv2/opencv.hpp>
#include <cmath>
const double PI = 3.141592653589793;
void createCircularDotScreen(cv::Mat& dst, const cv::Mat& src, double angle_deg, double lpi) {
double angle_rad = angle_deg * PI / 180.0;
double dpi = 96.0; // 假设屏幕DPI为96
double spacing = dpi / lpi; // 计算网点间距(像素)
dst.create(src.size(), CV_8UC1);
cv::Point2f center(src.cols / 2.0f, src.rows / 2.0f);
for (int y = 0; y < src.rows; ++y) {
for (int x = 0; x < src.cols; ++x) {
// 坐标平移至中心
float x_rel = x - center.x;
float y_rel = y - center.y;
// 15度倾斜变换
float x_rot = x_rel * cos(angle_rad) - y_rel * sin(angle_rad);
float y_rot = x_rel * sin(angle_rad) + y_rel * cos(angle_rad);
// 计算网点中心位置
float x_center = round(x_rot / spacing) * spacing;
float y_center = round(y_rot / spacing) * spacing;
// 计算当前点到网点的距离
float distance = sqrt(pow(x_rot - x_center, 2) + pow(y_rot - y_center, 2));
float radius = spacing / 2.0;
// 获取原图像素值(0-255)
uchar pixel = src.at<uchar>(y, x);
float threshold = radius * (1.0 - pixel / 255.0);
// 决定是否填充网点
dst.at<uchar>(y, x) = (distance <= threshold) ? 0 : 255;
}
}
}
int main() {
cv::Mat src = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
if (src.empty()) return -1;
cv::Mat dotPattern;
createCircularDotScreen(dotPattern, src, 15.0, 60.0);
cv::imwrite("output.jpg", dotPattern);
return 0;
}
|
|