|
发表于 2024-12-17 12:10:31
|
显示全部楼层
要实现您描述的效果,即在不旋转图片的情况下达到类似旋转、绘制、再旋转回正常角度的效果,我们需要通过计算网格和圆心的位置来模拟这些旋转。具体实现中,将网点沿指定的角度排列,而不是简单地根据图像的行列直接绘制网点。
以下是实现思路的代码:
- #include <opencv2/opencv.hpp>
- #include <cmath>
- // 根据角度计算网格调整后的圆心
- cv::Point2f calculateRotatedCenter(int x, int y, int blockSize, double angleRad, const cv::Point2f& center) {
- double cosA = std::cos(angleRad);
- double sinA = std::sin(angleRad);
- int dx = x - center.x;
- int dy = y - center.y;
- float newX = dx * cosA - dy * sinA + center.x;
- float newY = dx * sinA + dy * cosA + center.y;
- return cv::Point2f(newX, newY);
- }
- void drawHalftone(cv::Mat& image, int blockSize, double angle) {
- double angleRad = angle * CV_PI / 180.0;
- cv::Point2f center(image.cols / 2.0f, image.rows / 2.0f);
-
- for (int y = 0; y < image.rows; y += blockSize) {
- for (int x = 0; x < image.cols; x += blockSize) {
- // 计算网格的中心
- cv::Point2f originalCenter(x + blockSize / 2.0f, y + blockSize / 2.0f);
- cv::Point2f rotatedCenter = calculateRotatedCenter(originalCenter.x, originalCenter.y, blockSize, -angleRad, center);
-
- // 确保在图像范围内
- if (rotatedCenter.x >= 0 && rotatedCenter.y >= 0 &&
- rotatedCenter.x < image.cols && rotatedCenter.y < image.rows) {
- // 提取原图的块并计算平均灰度值
- cv::Rect blockRect(x, y, blockSize, blockSize);
- cv::Mat block = image(blockRect);
- double avgGray = cv::mean(block)[0];
- double radius = (avgGray / 255.0) * (blockSize / 2.0);
- // 绘制圆形
- cv::circle(image, rotatedCenter, static_cast<int>(radius), cv::Scalar(0), -1);
- }
- }
- }
- }
- int main() {
- // 读取图像
- cv::Mat image = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE);
- if (image.empty()) {
- std::cerr << "读取图像失败!" << std::endl;
- return -1;
- }
- int blockSize = 10; // 网格块的大小
- double angle = 45; // 要模拟旋转的角度
- drawHalftone(image, blockSize, angle);
- // 显示结果
- cv::imshow("Halftone", image);
- cv::waitKey(0);
- return 0;
- }
复制代码
请确保替换 `"input.jpg"` 为实际图片路径。这段代码通过对网格的位置进行旋转计算,然后在相应的位置绘制圆点,从而模拟了旋转图片再画圆点的效果。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|