Ini dapat dicapai dengan konvolusi transformasi jarak.
Gunakan transformasi jarak di tepi topeng. Kemudian ambang transformasi jarak ini untuk menghapus nilai di luar jarak tertentu. Saya pikir rahasia untuk mendapatkan naungan adalah dengan menggabungkan hasil transformasi jarak dengan kernel yang terlihat seperti ini:
[ -1.0 -1.0 -1.0
-1.0 0.0 0.0
-1.0 0.0 1.0 ]
Ini akan membantu Anda memulai ke arah yang benar:
#include "opencv/cv.h"
#include "opencv/highgui.h"
using namespace cv;
using namespace std;
int main() {
Mat mask, dist, bevel;
mask = Mat::zeros(200, 400, CV_8U);
rectangle(mask, Point(30,30), Point(180,180), Scalar(255), -1);
circle(mask, Point(30,30), 50, Scalar(0), -1);
circle(mask, Point(180,180), 50, Scalar(0), -1);
circle(mask, Point(300,100), 75, Scalar(255), -1);
imshow("1",mask);
//find edges and invert image for distance transform
Canny(mask, dist, 50, 150);
dist = 255-dist;
distanceTransform(dist, dist, CV_DIST_L2, CV_DIST_MASK_5);
threshold(dist, dist, 20, 20, CV_THRESH_TRUNC);
blur(dist, dist, Size(3,3));
dist.convertTo(bevel, CV_8U);
equalizeHist(bevel, bevel);
imshow("2",bevel);
//convolve with secret sauce
float d[] = {-1,-2,-3,
-2, 0, 0,
-3, 0, 1 };
Mat kernel(3, 3, CV_32F, d);
kernel = kernel - mean(kernel)[0];
filter2D(dist, dist, CV_32F, kernel);
//normalize filtering result to [-1, 1]
double maxVal;
minMaxLoc(dist, NULL, &maxVal);
dist = 128 * dist / maxVal;
//convert and display result
dist.convertTo(bevel, CV_8U, 1, 128);
bevel = bevel.mul(mask)/255;
imshow("3", bevel);
waitKey(0);
}
Bevel dan Emboss Photoshop berfungsi dengan baik:
1) Hitung transformasi jarak dalam gambar saluran tunggal 8-bit sementara
Pahat menggunakan Transformasi Jarak Euclidean dengan metrik Chamfer (3x3, 5x5, atau 7x7 tergantung pada ukuran). Anda dapat menggunakan transformasi jarak euclidean yang tepat jika Anda mau, saya lebih suka yang dari Meijster karena dapat dibuat anti-alias ("Algoritma Umum untuk Menghitung Transformasi Jarak dalam Waktu Linear", MEIJSTER).
Smooth Bevel menggunakan transformasi jarak 5-7-11 Chamfer diikuti oleh dua aplikasi blur kotak, untuk menghasilkan peta benjolan.
2) Menerapkan pemetaan singkat ke gambar transformasi jarak menengah. Teknik asli Blinn cocok.
3) Untuk pelunakan, Anda dapat melakukan konvolusi pada normals permukaan atau Anda dapat memfilternya menggunakan kernel.
4) Dengan menggunakan bump map, normals permukaan digabungkan dengan sumber cahaya global untuk menghitung intensitas pencahayaan sebagai nilai -1 hingga 1 di mana nilai negatif adalah bayangan, nilai positif adalah highlight, dan nilai absolut adalah besarnya cahaya sumber.
5) Dua gambar sementara saluran tunggal 8-bit dihitung, satu dari intensitas sorotan dan yang lainnya dari bayangan. Dari sana adalah hal yang sepele untuk menggunakan setiap topeng untuk mewarnai lapisan menggunakan warna, mode campuran, dan opacity - satu topeng untuk highlight dan yang lainnya untuk bayangan.
Kode sumber Visual Basic untuk mengimplementasikan beberapa hal ini dapat ditemukan di sini:
http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=51640&lngWId=1
Silakan kunjungi proyek LayerEffects open source saya untuk mempelajari lebih lanjut:
https://github.com/vinniefalco/LayerEffects.git
Saya harap ini membantu seseorang.
sumber