ミドリ黄のプログラミングメモノート

主にUnity(C#)を中心としたプログラムの備忘録

C++ OpenCV ルックアップテーブル(LUT)の使い方





使用した素材

以下のプログラムで使用した画像はベイツ・イメージズ様のものです。それぞれの素材のリンクは以下の通りです。
綿雲が浮かぶ穏やかな青空
カラフルな原色系のかっこいい背景




概要

LUTはルックアップテーブル(Look Up Table)の略であり、入力された値に対して出力した値を割り当てた配列のことです。
OpenCVではこれを利用することで入力画像の画素値が0の部分を出力画像において255に変換するといった処理が可能になります。
for文を用いて処理するよりも処理時間が速くなったりするなどのメリットがあります




アルゴリズム

後述の様にLUTはC/C++では多次元配列のcv::Matを使うのですが、ここでは分かりやすくするために1次元配列(長さ256)で考えます
LUTの配列は入力画像の画素値をindexとして受け取り、そのindexのvalueを出力画像の画素値とします例えば、以下のようなLUTなら入力画像を画素値125を閾値として2値化するといった処理が可能になります。

index 0 1 124 125 126 254 255
value 0 0 0 255 255 255 255





C/C++での利用方法

LUTそのものは高さ1、幅256のcv::Mat型で宣言します。

cv::Mat lut = cv::Mat(1, 256, CV_8U);


入出力画像をsrc、dstとした場合先ほどの配列を用いると

cv::LUT(src, lut, dst);

とすることでLUTを適用することができます



使用例①(グレースケール画像の2値化)

プログラム

#include <opencv2/opencv.hpp>

int main(void)
{
	//入力画像と出力画像の宣言
	cv::Mat src, dst;

	//画像をグレースケールで読み込む
	src = cv::imread("読み込む画像のパス", 0);


	//LUTの作成
	cv::Mat lut = cv::Mat(1, 256, CV_8U);
	int thre = 125;
	for (int i = 0; i < lut.cols; i++) {
		lut.at<uchar>(0, i) = (i >= thre) ? 255 : 0;
	}

	//LUTの適用
	cv::LUT(src, lut, dst);

	//画像を表示
	cv::imshow("src", src);
	cv::imshow("dst", dst);

	//入力を受け付けたら終了
	cv::waitKey(0);

	return 0;
}



実行結果






カラー画像での使用方法

カラー画像に対してLUTを作成する場合は

cv::Mat lut = cv::Mat(1, 256, CV_8UC3);

というように3チャンネルで宣言する必要があります。


プログラム例②(カラー画像のR成分のみを取り出す)

#include <opencv2/opencv.hpp>

int main(void)
{
	//入力画像と出力画像の宣言
	cv::Mat src, dst;

	//画像をカラーで読み込む
	src = cv::imread("画像のパス");


	//LUTの作成
	cv::Mat lut = cv::Mat(1, 256, CV_8UC3);
	int thre = 125;
	for (int i = 0; i < lut.cols; i++) {
		//BGRの成分のうち、BとGを0にして、Rはそのまま
		lut.at<uchar>(0, i * 3) = 0;
		lut.at<uchar>(0, i * 3 + 1) = 0;
		lut.at<uchar>(0, i * 3 + 2) = i;
	}

	//LUTの適用
	cv::LUT(src, lut, dst);

	//画像を表示
	cv::imshow("src", src);
	cv::imshow("dst", dst);

	//入力を受け付けたら終了
	cv::waitKey(0);

	return 0;
}


実行結果