Bitmap alfa eğim algoritması?


14

Alfa bir yumru harita olarak kullanarak bir bitmap bir eğim efekti ekleyen bir algoritma oluşturmak için arıyorum.

Böyle bir şeyi nasıl yapabilirim? Aynasal aydınlatmayı denedim ama sadece gölgeyi değil vurgulamayı aldım.

Bahsettiğim etki (Photoshop kullanılarak yapılmış): resim açıklamasını buraya girin

Bunların tümü kullanılarak yapıldı size: 30px(bitmap konturundan eğim derinliği), angle 130, altitude 50.

Soldan sağa, yukarıdan aşağıya:

  1. Keski Sert eğim
  2. Keski Yumuşak Eğim
  3. Pürüzsüz Eğim
  4. Keski Sert ile soften: 16px- bulanık bir eğim?

Bu efektlerin her birini oluşturmaya çalışıyorum, temel eğimi nasıl oluşturabilirim? ve bu eğimden her birine ne getirmem gerekiyor?

Yanıtlar:


10

Bu, mesafe dönüşümünün bir dönüşümü ile gerçekleştirilebilir.

Maskenin kenarında bir mesafe dönüşümü kullanın. Sonra bu mesafeyi belirli bir mesafenin ötesindeki değerleri kaldırmak için dönüştürün. Gölgelemeyi elde etmenin sırrı, mesafe dönüşümü sonucunu şuna benzeyen bir çekirdekle birleştirmektir:

[ -1.0  -1.0  -1.0
  -1.0   0.0   0.0
  -1.0   0.0   1.0 ]

Bu, doğru yönde başlamanızı sağlayacaktır:

#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);

resim açıklamasını buraya girin

    //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);

resim açıklamasını buraya girin

    //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);

resim açıklamasını buraya girin

    waitKey(0);
}

Harika görünüyorlar! Yumuşatılmış olan bir bulanıklık gibi görünüyor, ama onlardan "Pürüzsüz Eğim" yapmaya nasıl giderim?
Shedokan

Pürüzsüz Eğim'in konvolüsyondan önce mesafe maskesini bulanıklaştırdığına ve Yumuşatmanın konvolüsyondan sonra sonucu bulanıklaştırdığına inanıyorum.
Matt M.

4

Photoshop Konik ve Kabartma öngörülebilir şekilde çalışır:

1) Geçici 8 bitlik tek kanallı bir görüntüde mesafe dönüşümünü hesaplayın

  • Keski, Pah metrikli Öklid Mesafe Dönüşümünü kullanır (boyuta bağlı olarak 3x3, 5x5 veya 7x7). İsterseniz tam bir öklid uzaklık dönüşümü kullanabilirsiniz, kenar yumuşatma yapılabileceğinden Meijster'dan birini tercih ederim ("Doğrusal Zamandaki Mesafe Dönüşümlerini Hesaplamak için Genel Bir Algoritma", MEIJSTER).

  • Pürüzsüz Eğim, bir oluk 5-7-11 mesafe dönüşümü ve ardından bir kutu bulanıklığının iki uygulamasını kullanır ve yumru haritasını oluşturur.

2) Ara mesafe dönüşüm görüntüsüne yumru eşleme uygulayın. Blinn'in orijinal tekniği uygundur.

3) Yumuşatma için yüzey normalleri üzerinde bir kıvrım yapabilir veya bir çekirdek kullanarak filtreleyebilirsiniz.

4) Yumru haritasını kullanarak, yüzey normalleri, negatiflerin gölgeler olduğu, pozitif değerlerin vurgulandığı ve mutlak değer ışığın büyüklüğü olduğu -1'den 1'e bir değer olarak aydınlatma yoğunluğunu hesaplamak için küresel ışık kaynağı ile birleştirilir. kaynak.

5) Biri açık ton yoğunluklarından diğeri gölgelerden olmak üzere iki adet 8 bit tek kanallı geçici görüntü hesaplanır. Oradan, bir rengi, karışım modunu ve opaklığı kullanarak katmanı renklendirmek için her maskeyi kullanmak önemsiz bir konudur - biri vurgulamalar için diğeri gölgeler için maske.

Bunlardan bazılarını uygulamak için Visual Basic kaynak kodu burada bulunabilir:

http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=51640&lngWId=1

Daha fazla bilgi edinmek için lütfen açık kaynak LayerEffects projemi ziyaret edin:

https://github.com/vinniefalco/LayerEffects.git

Umarım bu birine yardımcı olur.


Teşekkür ederim, bahsettiğiniz Gauss Mesafe Dönüşümü ile çok ilgileniyorum, mevcut herhangi bir kodun farkında mısınız? Formülleri iyi okuyamıyorum. :(
Shedokan

Daha önce yayınladığım bilgiler dışında GDT hakkında hiçbir şey bulamadım.
Vinnie Falco

"2) Mesafe dönüşüm görüntüsüne kabartma eşleme uygula" ile ne demek istiyorsun? Mesafe dönüşümü mesafeler verir (her piksel için 1 sayı), Kabartma eşlemesi normaller gerektirir (her piksel için 2 sayı) ... Neden bahsettiğinizden emin misiniz?
Ivan Kuckir

@IvanKuckir Daha açık olmalıydım - normal bir yüzey, mesafe dönüşümünü bir yükseklik haritası olarak ele alıp komşu dikey ve yatay değerlerden dx / dy hesaplayarak hesaplanabilir. Bu iki sayı, yumru eşlemesi için gerekli olan normal değerleri sağlar.
Vinnie Falco
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.