我正在尝试使用sobel运算符将高度图转换为法线贴图,使用一些opencv函数,这是我的代码;
cv::Mat src = cv::imread("C:/Users/Cihan/Desktop/aa.png");
cv::Mat src_gray;
GaussianBlur(src, src, cv::Size(3, 3), 0, 0, 4);
cvtColor(src, src_gray, CV_BGR2GRAY);
cv::Mat grad_x;
cv::Mat grad_y;
int ddepth = CV_16S;
int scale = 1;
int delta = 0;
cv::Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, 4);
cv::Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, 4);
//cv::imwrite("C:/Users/Cihan/Desktop/kk.png", grad_x);
cv::Mat abs_grad_x;
cv::Mat abs_grad_y;
cv::convertScaleAbs(grad_x, abs_grad_x);
cv::convertScaleAbs(grad_y, abs_grad_y);
cv::Mat imgNew(src.size().height, src.size().width, CV_8UC3);
for (int x = 0; x < src.size().height; ++x) {
for (int y = 0; y < src.size().width; ++y) {
float pixel_x = abs_grad_x.at<uint8_t>(x, y);
float pixel_y = abs_grad_y.at<uint8_t>(x, y);
Vec3f dx = Vec3f{ pixel_x, 0.0f,0.0f};
dx.normalize();
Vec3f dy = Vec3f{ 0.0f, pixel_y,0.0f};
dy.normalize();
Vec3f nm = dx.cross(dy);
nm.normalize();
nm = (nm * 127.5f) + Vec3f{ 128.0f, 128.0f, 128.0f };
auto& imgRGB = imgNew.at<cv::Vec3b>(x, y);
imgRGB[2] = static_cast<uint8_t>(nm.x());
imgRGB[1] = static_cast<uint8_t>(nm.y());
imgRGB[0] = static_cast<uint8_t>(nm.z());
}
}
cv::imwrite("C:/Users/Cihan/Desktop/tt.png", imgNew)
基本上我找到了x渐变和y渐变的图像用Sobel()然后我做了渐变的产品但是我的结果就是这个;
来自此;
答案 0 :(得分:0)
好的,我找到了解决方案,以防有人想要使用相同的算法;
cv::Mat src = cv::imread("C:/Users/Cihan/Desktop/aa.png");
cv::Mat src_gray;
cvtColor(src, src_gray, CV_BGR2GRAY);
cv::Mat grad_x;
cv::Mat grad_y;
int ddepth = CV_16S;
int scale = 1;
int delta = 0;
cv::Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta,1);
//cv::Mat M;
//M = src_gray.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
cv::Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta,1);
cv::Mat abs_grad_x;
cv::Mat abs_grad_y;
cv::convertScaleAbs(grad_x, abs_grad_x,0.125,127.5);
cv::convertScaleAbs(grad_y, abs_grad_y,0.125,127.5);
cv::imwrite("C:/Users/Cihan/Desktop/kk.png", abs_grad_x);
cv::imwrite("C:/Users/Cihan/Desktop/ll.png", abs_grad_y);
cv::Mat imgNew(src.size().height, src.size().width, CV_8UC3);
for (int y =0; y < src.size().height; ++y) {
for (int x=0; x < src.size().width; ++x) {
float pixel_x = ((static_cast<float>
(abs_grad_x.at<uint8_t>(x, y))*2.0f)/255.0f)-1.0f;
float pixel_y = -(((static_cast<float>
(abs_grad_y.at<uint8_t>(x, y))*2.0f)/255.0f)-1.0f);
Vec3f dx = Vec3f{ 1.0f, 0.0f,pixel_x };
dx.normalize();
Vec3f dy = Vec3f{ 0.0f, 1.0f,pixel_y };
dy.normalize();
Vec3f nm = dx.cross(dy);
nm.normalize();
nm = (nm * 128.0f) + Vec3f{ 128.0f, 128.0f, 128.0f };
auto& imgRGB = imgNew.at<cv::Vec3b>(x, y);
imgRGB[2] = static_cast<uint8_t>(nm.x());
imgRGB[1] = static_cast<uint8_t>(nm.y());
imgRGB[0] = static_cast<uint8_t>(nm.z());