Windows でプログラムを書いたことがある人なら、誰でも多かれ少なかれビットマップを使ったことがあると思います。ほとんどの人は、成熟した完全な DIB クラス ライブラリ (CxImage、CDIB など) をインターネットからダウンロードして使用していますが、将来簡単に拡張して使用できるように、独自のカプセル化された DIB クラス ライブラリ セットを持っている人もいます。 (GDI+ は近年強力な勢力として登場しました。スケーリング、回転、グラデーションの塗りつぶしなど、特定の処理面で比類のない速度と品質を提供します。ただし、完全な画像処理プログラムを作成する場合、これを直接使用するとアーキテクチャ設計に困難が生じます。使用する前に、アダプター モードでカプセル化することができます)。 このとき、画像処理操作が必要になった場合はどうすればよいでしょうか? OO 経験のない多くのC++プログラマー (1 年前の私のように) は、クラスにメソッドを直接追加するかもしれません。
ここでは 2 つの例を示します (それぞれ、色の反転と RGB 値の調整を実現する)。実際には、明るさ、コントラスト、彩度など、このような操作は多数あります。さて、振り返ってみてください。これらのメソッドを追加するには、どのような手順を踏むのでしょうか。おおおお、RCP (同僚の発明、フルネーム: ラピッド コピー ペースト^-^)、最初の手順は、上記のコードの一部をコピーし、インターフェイスと処理部分を変更することです。ここでのデモ コードは短く、バグと一緒にコピーされることはありませんが、時限爆弾がもう 1 つあります。ある日、上司から「長い間待つのは耐えられないので、進捗バーを追加してください…」と言われました。グローバル変数を追加したり、各関数にパラメータを追加したりすることもできますが、同じことが続きます。つまり、これらすべての処理関数のコードを変更する必要があり、内部の呪いによって、それらのいずれかを変更する必要がなくなるわけではありません。この時点で、バグはすでに攻撃の機会をうかがっています... しかし、苦難の時代はまだまだ終わりません。 1 か月後、上司から突然、地域処理機能の追加を依頼され、さらに 1 か月後... 戻ってコードをもう一度見てみますか?そうです、赤いコードを除いて、他のすべてはまったく同じなので、これらのアルゴリズムを分離することは可能ですか?標準ライブラリの qsort や windows でよく使用されるコールバック メソッドをすぐに思い浮かべるかもしれません。では、これを実装してみましょう:
まあ、それは良いことです。アルゴリズムが 1 つの関数にまで削減され、問題は解決したようです。 Invert の処理はうまくいっていますが、AdjustRGB の処理で問題が発生しました。RGB の 3 つの調整パラメータを渡すにはどうすればよいでしょうか?グローバル変数/メンバー変数を追加することで、インターフェイスにパラメーターが 1 つだけになりますか?これは一つの方法ですが、クラスメソッドの数が増えるとプログラムの可読性や保守性が急激に低下し、変更前よりも影響が悪くなります。 では、高度な抽象化と優れたインターフェースを実現するにはどうすればよいでしょうか?私たちは OO (オブジェクト指向) を現場に招き、その実装について話をしてもらいました。次の派生関係を設計します。
次に、イメージクラスを次のように変更します。
(上記は単なる基本的なフレームワークであり、構築時に RECT パラメータを渡すことで、領域処理パラメータを簡単に追加できます。) オブジェクトは本当に素晴らしいものです。オブジェクトは、外の世界へのシンプルなインターフェースを提供することができ、また、オブジェクト自体に多くの追加情報をカプセル化することができます。 さて、結果をテストしましょう。画像の奇数行を黒に、偶数行を白に設定する操作を追加します。
次に、次の呼び出しを行います。
なんと調和がとれていて美しいのでしょう。アルゴリズム設計者は、プログレスバーや領域をどのようにサポートするかを考える必要はなく、独自のアルゴリズムを記述するだけで済みます。よくデザインされたAKのような感じで、弾(オブジェクト)を追加し続けることができます^-^ この時点で、作業は完了しているはずです。まだ質問がありますか? 待ってください、急がないでください。何かがおかしいのです。このアルゴリズムを追加した後、コンパイルになぜこんなに時間がかかるのでしょうか? 問題は、目立たないことにあります。
画像は、画像処理の最も低レベルのオブジェクトです。プロジェクト内のすべてのファイルは、これを直接的または間接的に含みます。したがって、image.h 自体とそれに含まれる .h ファイルを変更すると、ほぼプロジェクト全体がビルドされます。これはもちろん耐え難いことです。解決策は、「前方宣言」を使用することです。PixelHandler インターフェイスでは、その参照のみが必要なためです (つまり、私 (インターフェイス) は、渡されたクラスの内部構造を知る必要はなく、32 (64) のメモリ アドレスのみを渡す必要があります)。 したがって、私たちは
次と置き換えます:
次に、PixelProcessor.h を .cpp ファイルに含めます。この方法では、PixelProcessor.h への変更は .cpp ファイルの再コンパイルのみにつながるため、コンパイル時間が大幅に節約されます。 要約: 1) 可能であれば、プログラミング時に「コードのコピー」について考えないでください。結局のところ、OO は抽象化とコードの再利用のために生まれました。 2) 必要でない限り、クラス メンバー変数と関数パラメーターは、可能な限りポインターまたは参照に置き換える必要があります。これにより、.h に含まれる他の .h ファイルの数が減り、それらを前方宣言に置き換えることができるため、コンパイル時間が短縮され、将来的に相互インクルードされる可能性も減ります。 3) 最後に、効率の問題についてお話ししましょう。ピクセルごとに仮想関数を呼び出すとパフォーマンスに影響が出ると言う人もいるかもしれません。これは事実ですが、実際の損失は想像よりもはるかに小さいです。実際にテストしてみましたが、1024*768 の画像にネガティブ処理を実行すると、速度の低下はわずか 5% 程度です。複雑な処理 (明るさ/コントラスト/ガンマ) を実行する場合、この低下は完全に無視できます。結局のところ、余分なコードはスタック アクセスとテーブル検索だけであり、浮動小数点除算などの時間のかかる命令ではありません。 |
<<: SQL SERVER データマイニング: クラスタリングアルゴリズムとシーケンシャルクラスタリングアルゴリズムの理解
誰もが美を愛しますが、誰もが生まれながらに美しさを持っているわけではないので、さまざまな種類の写真美...
教育部はこのほど記者会見を開き、「高等学校一般教育課程計画及び中国語等教科教育課程基準(2017年版...
簡単に体験できるものではないため、自動運転技術が実用化にはまだ遠いと感じている人も多いでしょう。しか...
この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...
この記事は、Heart of Autonomous Driving の公開アカウントから許可を得て転...
[[349302]]今日、職場での学習は課題に直面しています。高度な分析、人工知能、ロボットが職場...
新たな常態に対応するために自動化プロセスを拡大多くの企業は、ニューノーマルに対処するための重要な技術...
この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...
[[436583]] [51CTO.com クイック翻訳]人工知能という用語は、20 世紀半ばに生ま...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...