๐Ÿฆ„AI/Computer Vision

[Computer Vision/OpenCV] 2. Image Resolution

mingyung 2025. 3. 8. 17:49

 

 

1. Image Quality

์ด๋ฏธ์ง€์˜ ์งˆ์€ ์–ด๋–ค ๋ถ€๋ถ„์—์„œ ๊ฒฐ์ •๋ ๊นŒ?

๋จผ์ €, ์ด๋ฏธ์ง€์˜ ๋Œ€๋น„๊ฐ€ ์„ ๋ช…ํ•˜๊ณ , ๋””ํ…Œ์ผํ•ด์•ผ ํ•œ๋‹ค.

๋‘๋ฒˆ์งธ๋กœ๋Š”, Splatial Resolution๊ณผ Intensity Quantization์ด ๋†’์€ ์ˆ˜์ค€์œผ๋กœ ๋˜์–ด์•ผ ํ•œ๋‹ค.

 

์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด์„œ ์ดํ•ดํ•ด ๋ณด์ž

 

๋งจ์œ„์˜ ์‚ฌ์ง„์€ ์›๋ณธ ์‚ฌ์ง„์ด๋‹ค.

 

์•„๋ž˜ ์™ผ์ชฝ์‚ฌ์ง„๋ถ€ํ„ฐ ์‚ดํŽด๋ณด์ž. ์ด ์‚ฌ์ง„์˜ ์งˆ์ด ์ข‹์ง€ ์•Š์€ ์ด์œ ๋Š” Spatial Resolution์— ์žˆ๋‹ค.

์•„๋ž˜ ์˜ค๋ฅธ์ชฝ ์‚ฌ์ง„์„ ๋ณด์ž. ์ด ์‚ฌ์ง„์˜ ์งˆ์ด ์ข‹์ง€ ์•Š์€ ์ด์œ ๋Š” Intensity Quantization์— ์žˆ๋‹ค.

์ง€๊ธˆ๋ถ€ํ„ฐ Spatial Resolution๊ณผ Quantization์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•ด ๋ณด์ž.

2. Spatial Resolution

Spatial Resolution์€ ์˜์ƒ์—์„œ ๋‘ ์  ์‚ฌ์ด์˜ ์ตœ์†Œ๊ฑฐ๋ฆฌ๋ฅผ ์ธก์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์ด๋‹ค. ์ฆ‰, ์ฃผ์–ด์ง„ ์˜์ƒ์—์„œ ๋‘๊ฐœ์˜ ์ธ์ ‘ํ•œ ๋ฌผ์ฒด ์‚ฌ์ด๋ฅผ ๊ตฌ๋ณ„ํ•˜๋Š” ์ตœ์†Œ๊ฐ/๊ฐ„๊ฒฉ์„ ๋งํ•œ๋‹ค.

๊ณต๊ฐ„ ํ•ด์ƒ๋„๋Š” ํ”ฝ์…€์˜ ํฌ๊ธฐ, spatial quantization, ๋ Œ์ฆˆ์˜ ์ดˆ์ ๊ฑฐ๋ฆฌ, ์นด๋ฉ”๋ผ์™€ ๊ด‘ํ•™์‹œ์Šคํ…œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

๊ณต๊ฐ„ ํ•ด์ƒ๋„๊ฐ€ ๋†’์€ ์ˆ˜๋ก ๋” ์ž‘์€ ๋ฌผ์ฒด๋ฅผ ๋” ์ž˜ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

๊ณต๊ฐ„ ํ•ด์ƒ๋„๊ฐ€ ๋†’๋‹ค = ํ•œ ํ”ฝ์…€์ด ์ž‘์€ ์˜์—ญ์„ ๋‚˜ํƒ€๋ƒ„ = ๊ฐ™์€ ๋ฉด์ ์˜ ์˜์ƒ์„ ํ‘œํ˜„ํ•˜๋Š” ํ”ฝ์…€์˜ ์ˆ˜๊ฐ€ ๋งŽ์•„์ง = ์ž‘์€ ๋ฌผ์ฒด๋„ ๋” ์„ ๋ช…ํ•˜๊ฒŒ ๊ตฌ๋ณ„๊ฐ€๋Šฅํ•ด์ง

๊ณต๊ฐ„ ํ•ด์ƒ๋„๊ฐ€ ๋‚ฎ๋‹ค = ํ•œ ํ”ฝ์…€์ด ๋” ํฐ ์˜์—ญ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค = ๊ฐ™์€ ๋ฉด์ ์˜ ์˜์ƒ์„ ํ‘œํ˜„ํ•˜๋Š” ํ”ฝ์…€์˜ ์ˆ˜๊ฐ€ ์ž‘์•„์ง = ๋ฌผ์ฒด ๊ฐ„์˜ ๊ฒฝ๊ณ„๊ฐ€ ํ๋ฆฟํ•ด์ง„๋‹ค.

 

Spatial Resolution ์ค„์—ฌ๋ณด๊ธฐ

์ง์ ‘ lena ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€์˜ spatial resolution์„ ์ค„์—ฌ๋ณด์ž.

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat downSpatialResolution(Mat input_img) {

    Mat img = input_img.clone();

    // Down Sampling (1/4) 
    // ๋‹ค์šด ์ƒ˜ํ”Œ๋ง ํ•˜๋ฉฐ 16๊ฐœ ํ”ฝ์…€ ์ค‘ 15๊ฐœ์˜ ํ”ฝ์…€์ด ์‚ฌ๋ผ์ง„๋‹ค.
    // 512x512 -> 128x128
    resize(img, img, Size(img.cols / 4, img.rows / 4));

    // Up Sampling (4)
    // ๋‹ค์‹œ ์‚ฌ๋ผ์กŒ๋˜ 15๊ฐœ์˜ ํ”ฝ์…€์€ ๋‚จ์•„์žˆ๋˜ 1๊ฐœ ํ”ฝ์…€์˜ ๊ฐ’์œผ๋กœ ์ฑ„์›Œ์ง„๋‹ค
    // 128x128 -> 512x512
    resize(img, img, Size(img.cols * 4, img.rows * 4));

    return img;
}

int main() {
    //์ด๋ฏธ์ง€ ํŒŒ์ผ ์ฝ์–ด์˜จ๋‹ค
    Mat img = imread("lena.jpg",IMREAD_COLOR);
    if (img.empty()) {
        std::cout << "Could not open or find the image" << std::endl;
        return -1;
    }
    //๊ณต๊ฐ„ ํ•ด์ƒ๋„๋ฅผ ์ค„์ธ๋‹ค.
    Mat img_2 = downSpatialResolution(img);

    Mat combined;
    hconcat(img, img_2, combined);

    // ํ•ฉ์นœ ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œ
    imshow("Comparison: Original vs Processed", combined);

    waitKey(0);

    return 0;
}

 

3. Intensity Quantization

์•ž์„  ํฌ์ŠคํŒ…์—์„œ ์‚ดํŽด๋ณธ ๋ฐ”์— ์˜ํ•˜๋ฉด ์šฐ๋ฆฌ๋Š” ๋น›์˜ ๊ฐ•๋„๋ฅผ 0-255(8 bit)์˜ ๊ฐ’์œผ๋กœ quantizationํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

์ด๊ฒƒ์„ ๋” ์ž‘์€ ํฌ๊ธฐ๋กœ ์–‘์žํ™” ํ•œ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ์ƒ‰์„ ๋””ํ…Œ์ผํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋‹ค. 

 

๊ธฐ์กด์— 8bit๋กœ ํ‘œํ˜„ํ•˜๋˜ intensity๋ฅผ 2bit์œผ๋กœ ์–‘์žํ™” ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ž.

์ด๋ ‡๊ฒŒ ๋  ๊ฒฝ์šฐ ๊ธฐ์กด 8bit๋กœ 0-63์˜ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์€ 2bit์—์„œ๋Š” ๋ชจ๋‘ ์ผ๊ด„์ ์œผ๋กœ 0์œผ๋กœ ์–‘์žํ™” ๋˜๊ฒŒ๋œ๋‹ค. ์ด๊ฒƒ์ด intensity quantization์— ๋”ฐ๋ผ ์ด๋ฏธ์ง€์˜ ์ƒ‰์ด ๋‹จ์ˆœํ•ด์ง€๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ๋Š”๋‹ค

์œ„์˜ ์—ด๊ธฐ๊ตฌ ์ด๋ฏธ์ง€๋Š” 8bit๊ฐ€ ์•„๋‹Œ 3bit์œผ๋กœ intensity๋ฅผ ์–‘์žํ™” ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ‰์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.

 

Intensity Quantization ์ค„์—ฌ๋ณด๊ธฐ

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat downIntensityQuantization(Mat input_img) {
	Mat img = input_img.clone();
	img.convertTo(img, CV_8U);

	for (int c = 0; c < img.channels(); c++) {
		Mat channel;
		extractChannel(img, channel, c);  // ์ฑ„๋„ ์ถ”์ถœ

		// Down Sampling (1/64) 
		// 0~255 -> 0,1,2,3(2bit) 
		channel = channel / 64;

		// Up Sampling (64)
		// 0,1,2,3 -> 0,64,128,192 
		channel = cv::min(channel * 64, 255);

		// ์ฑ„๋„ ๋‹ค์‹œ img์— ํ•ฉ์นจ
		insertChannel(channel, img, c);
	}

	img.convertTo(img, input_img.type()); //์›๋ž˜ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜
	return img;
}

int main() {
	//์ด๋ฏธ์ง€ ํŒŒ์ผ ์ฝ์–ด์˜จ๋‹ค
	Mat img = imread("lena.jpg", IMREAD_COLOR);
	if (img.empty()) {
		std::cout << "Could not open or find the image" << std::endl;
		return -1;
	}

	Mat img_2 = downIntensityQuantization(img);

	Mat combined;
	hconcat(img, img_2, combined);

	// ํ•ฉ์นœ ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œ
	imshow("Comparison: Original vs Processed", combined);

	waitKey(0);

	return 0;
}