5

レンダリングされた Web ページをクライアントに提供するカスタム シンクライアント サーバーを開発しています。サーバーは、HTML レンダリング エンジンを提供する Webkit を使用して、マルチコア Linux ボックスで実行されます。

唯一の問題は、クライアントの表示が 4 ビット (16 色) のグレースケール パレットに制限されていることです。私は現在、LibGraphicsMagick を使用して画像をディザリング (RGB->4 ビット グレースケール) していますが、これはサーバー パフォーマンスの明らかなボトルネックです。プロファイリングでは、GraphicsMagick ディザリング関数の実行に 70% 以上の時間が費やされていることが示されています。

優れた高性能ソリューションを求めて、stackoverflow と Interwebs を調査しましたが、さまざまな画像操作ライブラリとディザリング ソリューションのベンチマークを誰も行っていないようです。

私はもっ​​と喜んで見つけます:

  1. RGB イメージの 4 ビット グレースケールへのディザリング / ハーフトーン化 / 量子化に関して、最もパフォーマンスの高いライブラリは何ですか。
  2. 特殊なディザリング ライブラリやパブリック ドメインのコード スニペットを教えてもらえますか?
  3. 高性能に関してグラフィックスを操作するためにどのライブラリを好みますか?

C 言語ライブラリが優先されます。

4

5 に答える 5

2

テストなしで Adisak が提供するリストから、私はAfterImageに賭けます。Afterstep の人々はスピードに夢中で、巧妙なアルゴリズムについても説明しています。

サーバーに OpenGL を備えたまともな PCI-express グラフィックス カードを装備できる場合は、別のアプローチを取ることができます。以下はNvidiaのスペックです。「インデックスモード」で検索してください。できることは、16 または 256 色の表示モードを選択し、画像を平らな多角形 (立方体の側面など) のテクスチャとしてレンダリングしてから、フレームを読み戻すことです。

OpenGL カードからフレームを読み取る場合、カードの帯域幅が良好であることが重要であるため、PCI-express が必要になります。ドキュメントにあるように、適切な効果を得るには、インデックス モードで色を選択する必要もあります。

于 2009-10-27T08:32:32.300 に答える
2

選択したアルゴリズムによっては、ディザリングにかなりの時間がかかります。

Bayer (Matrix)およびFloyd-Steinberg (Diffusion) ディザリングを実装するのはかなり簡単です。

ベイヤー フィルタリングは、MMX/SSE を使用して並列ピクセルを処理するようにコーディングすると、非常に高速になります。GPUシェーダーを使用してディザリング/変換を行うこともできます。

FWIW、あなたはすでに GraphicsMagick を使用していますが、ここに OSS グラフィック ライブラリの完全なリストがあります。

于 2009-09-28T19:47:30.490 に答える
1

以下は、ハーフトーン処理のための Floyd-Steinberg メソッドの実装です。

#include <opencv2/opencv.hpp>

using namespace cv;

int main(){

uchar scale = 128; // change this parameter to 8, 32, 64, 128 to change the dot size
Mat img = imread("../halftone/tom.jpg", CV_LOAD_IMAGE_GRAYSCALE);
for (int r=1; r<img.rows-1; r++) {
    for (int c=1; c<img.cols-1; c++) {
        uchar oldPixel = img.at<uchar>(r,c);
        uchar newPixel = oldPixel / scale * scale;
        img.at<uchar>(r,c) = newPixel;
        int quantError = oldPixel - newPixel;
        img.at<uchar>(r+1,c)   +=  7./16. * quantError;
        img.at<uchar>(r-1,c+1) +=  3./16. * quantError;
        img.at<uchar>(r,c+1) +=  5./16. * quantError;
        img.at<uchar>(r+1,c+1) +=  1./16. * quantError;
    }
}
imshow("halftone", img);
waitKey();
}
于 2013-07-27T17:54:53.420 に答える