Nasıl bir resmin yüksek kalitede ölçeklendirme yaparsınız?

oy
18

Ben C / C ++ bir 32 bitlik RGBA ölçeklemek üzere bazı kod yazıyorum. Ben biraz başarılı olmuştur birkaç deneme yazdım, ama onlar yavaş ve en önemlisi ölçekli görüntünün kalitesi kabul edilemez.

Aynı OpenGL tarafından Ölçeklenmiş resim (yani benim ekran kartı) ve benim rutin karşılaştırıldı ve kalitesinde birbirlerinden kilometrelerce bu. Google Code, Aranan Biraz ışık (SDL, Allegro, WxWidgets, CxImage, GD, ImageMagick, vs.) döken düşündüm şey kaynak ağaçları dolaştılar ama genellikle kod dolambaçlı ya ve yer ya da delik deşik ile her yerinde dağınık ettik montajcı ve çok az veya hiç yorumlar. Ayrıca Wikipedia'da birden çok makale okudum ve başka yerlerde ve sadece ihtiyacım olanı net bir açıklama bulamıyorum. Ben interpolasyon ve örnekleme temel kavramlarını anlıyorum ama algoritma hakkını almak için mücadele ediyorum. Bir rutin için harici kütüphaneye güvenmek ve geri görüntü formatı ve dönüştürmek zorunda kalmak istediğiniz değil. Ayrıca, ben zaten kendim nasıl bilmek istiyorum. :)

Daha önce yığın taşması üzerine sorulan benzer bir soru gördük, ama gerçekten bu şekilde yanıt verilmezse, ama doğru yönde bana dürtmek yardımcı olabilecek biri vardır diye umuyorum. Belki bana öğrenmek ve yapmak yardımcı olacak bazı makaleler veya sahte kod ... şey bana gelin.

İşte aradığım budur:

  1. Hiçbir montajcı (birden çok işlemci türleri için çok taşınabilir kod yazıyorum).
  2. Dış arşivlerine hiçbir bağımlılıkları.
  3. Ben AŞAĞI ölçeklendirme ile öncelikle endişe duyuyorum, ama aynı zamanda daha sonra bir ölçek kadar rutin yazmak gerekir.
  4. Sonuç ve algoritmanın netlik kalitesi en önemlisidir (ileride tekrar optimize edebilirsiniz).

Benim rutin esasen aşağıdaki biçimdedir:

DrawScaled(uint32 *src, uint32 *dst, 
      src_x, src_y, src_w, src_h, 
      dst_x, dst_y, dst_w, dst_h );

Teşekkürler!

GÜNCELLEME: Çok fazla görüntüyü bulanıklaştırır ölçütlendirilmesi için bir kutu resample daha gelişmiş bir şeye ihtiyacım, netleştirmek için. Ne istediğinizi biraz yani her hedef piksel keskin şeyler tutan bir ağırlık algoritması ile kombine tüm katkı kaynak piksellerden hesaplanan bir bikübik yükseltme algoritmaya ters (olan bicubic (veya başka) filtrenin bir çeşit şüpheli.

Örnek

İşte ben 55x55 ölçeklenmiş bir 256x256 bitmap üzerinde istediğini vs WxWidgets BoxResample algoritmadan ne çekiyor bir örnek.

  • www.free_image_hosting.net/uploads/1a25434e0b.png

Ve sonunda:

  • www.free_image_hosting.net/uploads/eec3065e2f.png

Orijinal 256x256 görüntü

Oluştur 09/12/2008 saat 16:05
kaynak kullanıcı
Diğer dillerde...                            


11 cevaplar

oy
2

Ben gerektiği gibi değiştirmek için oldukça basit WxWidgets uygulanmasını buldum. Her C ++ orada taşınabilirlik yüzden hiçbir sorun olduğunu. Tek fark bunların uygulanması RGB bir bayt düzen ve ayrı bir dizide alfa bileşeni ile (ı görüntüleri nasıl olsa başa kolay yolu olarak görüyorum) işaretsiz char dizileri ile çalışmasıdır.

Eğer WxWidgets kaynak ağacındaki "src / ortak / image.cpp" dosyası başvurursanız orada bir kutu örnekleme yöntemi "wxImage :: ResampleBox" ve "wxImage denilen bir yukarı Ölçekleyicili fonksiyonu kullanan bir aşağı-sampler fonksiyonu :: ResampleBicubic".

Cevap 09/12/2008 saat 16:18
kaynak kullanıcı

oy
2

Görüntüleri yeniden örneklemek için Oldukça basit ve iyi algoritmadır Bicubic enterpolasyon wikipedia yalnız, bu uygulamaya geçebilmesi için gereken tüm bilgi vardır.

Cevap 09/12/2008 saat 16:21
kaynak kullanıcı

Cevap 09/12/2008 saat 16:37
kaynak kullanıcı

oy
1

Kullanmayı deneyin , Adobe Genel Resim Kitaplığı ( http://opensource.adobe.com/wiki/display/gil/Downloads bir şey hazır ve sadece bir algoritma istiyorsanız).


Alıntı: http://www.catenary.com/howto/enlarge.html#c

Büyütün veya azaltın - K Kaynak Kod Victor Görüntü İşleme Kütüphanesi 32-bit Windows v 5.3 veya üstü için gerektirir.


int enlarge_or_reduce(imgdes *image1)
{
   imgdes timage;
   int dx, dy, rcode, pct = 83; // 83% percent of original size

   // Allocate space for the new image
   dx = (int)(((long)(image1->endx - image1->stx + 1)) * pct / 100);
   dy = (int)(((long)(image1->endy - image1->sty + 1)) * pct / 100);
   if((rcode = allocimage(&timage, dx, dy,
      image1->bmh->biBitCount)) == NO_ERROR) {
      // Resize Image into timage
      if((rcode = resizeex(image1, &timage, 1)) == NO_ERROR) {
         // Success, free source image
         freeimage(image1);
         // Assign timage to image1
         copyimgdes(&timage, image1);
         }
      else // Error in resizing image, release timage memory
         freeimage(&timage);
      }
   return(rcode);
}

Bu örnek bir görüntü alanını yeniden boyutlandırır ve yeni asıl resmi değiştirir.

Cevap 09/12/2008 saat 16:44
kaynak kullanıcı

oy
1

Sevgili ana bilgisayardan genel bir madde: Daha İyi Görüntü boyutlandırma'nın , çeşitli algoritmaların nispi niteliklerini tartışmaya (ve başka CodeProject makalesine bağlar).

Cevap 09/12/2008 saat 17:12
kaynak kullanıcı

oy
1

Intel ailesi işlemciler için optimize edilmiş yüksek hızlı enterpolasyon algoritmaları sağlamak IPP kütüphaneleri vardır. Çok iyi ama olsa özgür değildir. Aşağıdaki linke bir göz atın:

Intel IPP

Cevap 09/12/2008 saat 17:33
kaynak kullanıcı

oy
0

Bir göz atın ImageMagick'in yeniden ölçeklendirme filtreleri her türlü yapar.

Cevap 09/12/2008 saat 18:57
kaynak kullanıcı

oy
2

OpenGL vektör etki alanında ölçeklendirme yapıyor olması mümkün mü? Eğer öyleyse, herhangi bir piksel tabanlı ölçekleme kalitesinde yanına olacak hiçbir yolu yoktur. Bu vektör tabanlı görüntülerin büyük bir avantajdır.

bikübik algoritması eserler vs keskinlik için ayarlanmış olabilir - Ben ne zaman düzenleyebilirsiniz edeceğiz bir bağlantı bulmak için çalışıyorum.

Düzenleme: Bu bağlantının altındaki başvuruda bulunulan, aklımdan Mitchell-Netravali eser oldu:

http://www.cg.tuwien.ac.at/~theussl/DA/node11.html

Ayrıca içine görünebilir Lanczos yeniden örnekleme bikübik alternatif olarak.

Cevap 09/12/2008 saat 19:00
kaynak kullanıcı

oy
1

> Sürekli - - düzgün bir görüntüyü yeniden örnekleyerek karışan> ayrık akış ne gerçekten anlamakta güçlük ediyoruz ayrık olduğu gibi geliyor. Size ihtiyacınız bu fikir vermek yardımcı olabilecek iyi bir teknoloji raporu Alvy Ray Smith'in olan bir Piksel mı Değil Bir Küçük Meydan .

Cevap 09/12/2008 saat 20:41
kaynak kullanıcı

oy
0

Bir takip olarak, Jeremy Rudd yayınlanan bu makaleyi yukarıda. Bu iki geçiş yeniden boyutlandırma, süzüldü uygular. Kaynaklar C # ama ben liman can bu denemeye o kadar net görünüyor. Ben (çok kötü değişken adları) anlamak çok zor oldu dün çok benzer C kodu bulundu. Ben sıralamak İşsiz bunu var, ama çok yavaş ve benim adaptasyon bir hata olduğuna inanmak götürdü iyi sonuçlar vermedi. Ben deneyeceğim referans olarak bu ile sıfırdan yazmak iyi şans olabilir.

Ama belki de tek geçişte, bunu yapmanın daha hızlı bir yöntem olmadığını merak nasıl iki geçiş algoritması çalışmaları dikkate?

Cevap 09/12/2008 saat 21:07
kaynak kullanıcı

oy
2

Şimdi orijinal görüntüyü görmesini, ben OpenGL en yakın komşu algoritması kullanılarak olduğunu düşünüyorum. Sadece o boyutlandırmak için mümkün olan en basit yoludur, ama aynı zamanda en hızlı bu. Sadece olumsuz orijinal görüntüdeki herhangi detay varsa çok kaba görünüyor olmasıdır.

Fikir orijinal görüntüden eşit aralıklı numune almaktır; senin durumunda, 256 veya her 4.6545 üzerinden birinden 55. Sadece sayı yuvarlak piksel seçim olsun.

Cevap 10/12/2008 saat 04:20
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more