SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaで学ぶグラフィックス処理

画像を小刻みに回転して写真の傾きを補正する

アフィン変換の回転と拡大を同時に行う


  • X ポスト
  • このエントリーをはてなブックマークに追加

デジタルカメラなどで写真を撮影するとき、誤って傾けてしまい、水平でなくなってしまうことがあります。そこで本稿では、補正画像を見ながら、0.5°刻みで画像を回転して補正する方法を紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 デジタルカメラなどで写真を撮影するとき、誤って傾けてしまい、水平でなくなってしまうことがあります。そこで本稿では、補正画像を見ながら、0.5°刻みで画像を回転して補正する方法を紹介します。

対象読者

 画像処理に興味を持ち、特に撮影した写真の補正に関心のある人。

必要な環境

 J2SE 5.0を使っていますが、これより古いバージョンでも、本稿のコードをコンパイルし実行することができます。ただし、添付のコンパイル済みアプレットの実行には、J2SE Runtime Environment 5.0が必要です。

概要

 デジタルカメラで写真を撮影するとき、液晶モニターが見にくくて、水平を十分確認できないことがあります。そのような状況下で撮影した写真に対して、傾斜を補正する方法を紹介します。有償無償の既存画像ソフトは、90、180、270度などの一定の角度しか回転できないものが多く、数度程度の補正が可能なソフトでも、周辺部の考慮がされていません。

 本稿では、0.5度単位で左右に回転ができ、周辺効果を無くして、画像サイズを元のままに保てるように、自動的に原画像を拡大する機能を付加しました。

画像の回転と拡大

 画像の回転や拡大縮小、平行移動などは「アフィン変換」と呼ばれ、Java APIにその処理を行うAffineTransformクラスがあります。また、類似の機能がGraphics2Dクラスにもあります。しかし、実際に試してみたところ、回転に際してジャギーが発生し、写真画像への応用には不適と判断しました。

 従って、既存のAPIを使用しないで、回転と拡大を同時に実行できるプログラムを作成しました。

画像の回転方法

 原画像を回転させるには、回転後の補正画像の座標を想定してスキャンし、補正画像のそれぞれの座標が原画像のどの場所に相当するかを計算します。

 図1に示すように、回転後の補正画像の座標(画像の中心から測った)から見たP点の位置を(i, j)とし、回転前の原画像の座標から見た位置を(xx, yy)とすると、図および式で示すような関係があります。図1の例では、回転前の画像から見て時計方向に角度θだけ画像を回転させていますが、θはマイナスをとることもできます。

図1 回転した補正画像の座標から、対応する原画像の座標を求める方法
図1 回転した補正画像の座標から、対応する原画像の座標を求める方法

画像の拡大方法

 回転させた補正画像を、原画像と同じサイズそのまま表示すると、画像に欠陥部分が生じます。これを、図2を使用して説明します。

図2 原画像をθだけ回転させた場合の拡大倍率の求め方
図2 原画像をθだけ回転させた場合の拡大倍率の求め方

 図2の左の図で、黒は回転後の補正画像の範囲、赤は回転する前の原画像を示します。分かりやすく説明すると、「原画像を回転する」ということは、「回転後の補正画像を正しく配置し」、「補正前の原画像をあらかじめ傾斜させて置き」、原画像を補正画像にそのままコピーすることと考えられます。

 これによると、倍率を同じにして原画像をθだけ回転すると、回転後の画像には、原画像データのない部分が生じることが分かります。緑色で示した部分は、欠如がなく、かつ原画像のサイズと相似ですので、緑色の範囲を黒の範囲に拡大する操作を行えば、欠けが生じないことになります。

 拡大倍率の計算は、図2の右の図を参照します。右の図は、左の図の一部分を取り出したもので、左の図の赤い画像の対角線の長さの半分を1とし、緑の画像範囲の対角線の半分をXとしています。このXを求めて、逆数を取れば、必要な拡大倍率zoomが得られます。

 ただし、画像を拡大して表示することは、原画像の座標位置を縮小しながら描画することなので、原画像の座標位置計算に当たっては、zoomで割り算をします(Xで乗算することと同じです)。

 回転角θには、正(時計方向)と負(反時計方向)がありますが、図2の左の図から想像できるように、左右を反転しただけですので、θの絶対値を取ればよく、式の形は変わりません。

最終的な座標変換の式

 以上の結果から、最終的に使用する座標変換の式は、下記の通りになります。ただし、iとjは回転後の補正画像のピクセルの座標位置で、対応する原画像のピクセルの座標位置をxxとyy(一般には整数値とならない)、右下がり方向の回転角をθ、画像の縦横比で決まる角度をαとします。

 

画像データの補間

 図3に示すように、座標変換の式により原画像の座標(xx, yy)を求めると、xx、yyは一般には整数ではなく実数となります。整数以外の座標には画像データ(ピクセル値)が存在ませんので、座標(xx, yy)の画像データを求めるには、data_0、data_1などの周辺データから補間によって求める必要があります。ただし、xはxxより負の無限大に近い整数、yはyyより負の無限大に近い整数とし、dx = xx - x、dy = yy - yとなります。dxとdyは1未満の実数値です。求める補間値をinter[k]とすると(kは色を表し、0は赤、1は緑、2は青を意味します)、まずAとBを線形補間で求め、AとBをさらに線形補間して求めます。

図3 補間値を求める原理
図3 補間値を求める原理

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
サンプルプログラムの概要

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Javaで学ぶグラフィックス処理連載記事一覧

もっと読む

この記事の著者

石立 喬(イシダテ タカシ)

1955年東京工大卒。同年、NECへ入社し、NEC初のコンピュータの開発に参画。磁気メモリ、半導体メモリの開発、LSI設計などを経て、1989年帝京大学理工学部教授。情報、通信、電子関係の教育を担当。2002年定年により退職し現在に至る。2000年より、Webサイト「Visual C++の勉強部屋」を公開。...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/398 2008/03/16 10:30

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング