我从黑色
cv::Mat
图像开始,但我想向其中添加 HSV。我怎样才能实现这个目标??
int RE_START = -2;
int RE_END = 1;
int IM_START = -1;
int IM_END = 1;
int MAX_ITER = 80;
int mandelbrot(std::complex<double> c){
std::complex<double> z{0,0};
int n = 0;
while (abs(z) <= 2 && n < MAX_ITER){
z = z*z + c;
n += 1;
}
return n;
}
int m;
int main()
{
//! [mandelbrot-transformation]
Mat mandelbrotImg(width, height,CV_8UC3, cv::Scalar(0, 0, 0));
Mat mandelHSV(width, height,COLOR_BGR2HSV);
float wid = (float)width;
float hei = (float)height;
int count = 0;
for (int x=0; x < width; x++){
for (int y=0; y<height; y++){
std::complex<double> c( RE_START + (x / wid) * (RE_END - RE_START),
IM_START + (y / hei) * (IM_END - IM_START));
m = mandelbrot(c);
double hue = (255 * m / (float)MAX_ITER);
double saturation = 255.0;
double value;
if (m < MAX_ITER) {
value = 255;
}else {
value = 0;
}
mandelbrotImg.at<cv::Vec3b>(x,y) = ((uchar)hue, (uchar)saturation, (uchar)value);
count++;
}
}
cv::cvtColor(mandelbrotImg, mandelbrotImg, COLOR_BGR2HSV);
imwrite("../img/mandle.png", mandelbrotImg);
}
};
这就是我目前所拥有的! 我不知道是否需要转换它或在像素位置分配 HSV 值。
现在的图像输出是:
预期输出:
您的原始代码中有很多问题,并且您当前的代码中仍然存在不少问题。
举几个例子:
cv::Mat
构造函数首先需要高度,然后是宽度。cv::Mat::at
方法首先需要 y 坐标,然后是 x。COLOR_HSV2BGR
不是COLOR_BGR2HSV
。mandelbrot
应该更好地通过 const&
接受参数
避免复制(效率问题)。abs(z) <= 2
,最好使用 norm(z) <= 4
,因为它可以避免计算 sqrt(效率问题)。double
中,因此我将所有 float
交换为 double
。cv::Mat
初始化为零值,因为稍后我们无论如何都会填充所有像素值。参见修复版本:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <complex>
static const int RE_START = -2;
static const int RE_END = 1;
static const int IM_START = -1;
static const int IM_END = 1;
static const int MAX_ITER = 80;
int mandelbrot(std::complex<double> const & c)
{
std::complex<double> z{ 0,0 };
int n = 0;
while (std::norm(z) <= 4 && n < MAX_ITER)
{
z = z*z + c;
n += 1;
}
return n;
}
int main()
{
int width = 960;
int height = 640;
cv::Mat mandelbrotImg(height, width, CV_8UC3);
double wid = (double)width;
double hei = (double)height;
double reWidth = RE_END - RE_START;
double imWidth = IM_END - IM_START;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
std::complex<double> c(RE_START + (x / wid) * reWidth, IM_START + (y / hei) * imWidth);
int m = mandelbrot(c);
double hue = (255 * m / (float)MAX_ITER);
double saturation = 255.0;
double value = (m < MAX_ITER) ? 255.0 : 0;
mandelbrotImg.at<cv::Vec3b>(y, x) = cv::Vec3b((uchar)hue, (uchar)saturation, (uchar)value);
}
}
cv::cvtColor(mandelbrotImg, mandelbrotImg, cv::COLOR_HSV2BGR);
cv::imwrite("../img/mandle.png", mandelbrotImg);
}