Table of Contents
목차
픽셀에 접근하는 방법
OpenCV에서 Mat 객체에 저장되어 있는 이미지의 픽셀에 접근하여 값을 가져오거나 값을 수정하는 법
1) 컬러 이미지의 픽셀에 접근하여 그레이 스케일 이미지로 변환한 후,
2) cvtColor
함수를 사용하여 컬러 이미지로 변환 cvtColor
3) 그런 다음 다시 픽셀에 접근하여 사과에 초록색 사각형을 그려보는 예제
C++
# include < opencv2/opencv.hpp> # include < iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img_color = imread("apple.png", IMREAD_COLOR);
// 이미지의 높이와 너비를 가져옵니다.
int height = img_color.rows;
int width = img_color.cols;
// 그레이 스케일 이미지를 저장할 Mat 객체를 생성합니다.
Mat img_gray(height, width, CV_8UC1);
// for 문을 돌면서 (x,y)에 있는 픽셀을 하나씩 접근합니다.
for (int y = 0; y < height; y++) {
// 속도 향상을 위해 y좌표를 사용하여 포인터 위치를 미리 계산합니다.
uchar* pointer_input = img_color.ptr<uchar>(y);
uchar* pointer_ouput = img_gray.ptr<uchar>(y);
for (int × = 0; × < width; x++) {
// 컬러 이미지의 (x,y)에 있는 픽셀의 b,g,r 채널을 읽습니다.
// 한 픽셀에 b,g,r 3개의 채널이 있기 때문에 x좌표에 3을 곱합니다.
// 한번에 3개의 열씩 이동하게 됩니다.
// 그레이 스케일 이미지를 접근할 경우에는 3을 곱할 필요가 없습니다.
uchar b = pointer_input[x * 3 + 0];
uchar g = pointer_input[x * 3 + 1];
uchar r = pointer_input[x * 3 + 2];
// (x,y) 위치의 픽셀에 그레이 스케일값이 저장됩니다.
// 평균값 사용하는 경우
// pointer_ouput[x] = (r + g + b) / 3.0;
// BT.709에 명시된 비율 사용하는 경우
pointer_ouput[x] = r * 0.2126 + g * 0.7152 + b * 0.0722;
}
}
// 결과 이미지에 컬러를 표시하기 위해 // 컬러 이미지로 변환합니다.
Mat img_result;
cvtColor(img_gray, img_result, COLOR_GRAY2BGR);
// y범위가 150~200, x범위가 200~250인 영역의 픽셀을 // 초록색 픽셀로 변경합니다.
for (int y = 150; y < 200; y++) {
uchar* pointer_input = img_result.ptr<uchar>(y);
for (int × = 200; × < 250; x++) {
pointer_input[x * 3 + 0] = 0; // b pointer_input[x * 3 + 1] = 255; // g pointer_input[x * 3 + 2] = 0; // r
}
}
// 원본 이미지와 결과 이미지가 보여집니다.
imshow("color", img_color);
imshow("result", img_result);
waitKey(0);
return 0;
}
PYTHON
import cv2 as cv
import numpy as np
img_color = cv.imread("apple.png", cv.IMREAD_COLOR)
# 이미지의 높이와 너비를 가져옵니다.
height, width = img_color.shape[:2]
# 그레이 스케일 이미지를 저장할 넘파이 배열을 생성합니다.
img_gray = np.zeros((height, width), np.uint8)
# for 문을 돌면서 (x,y)에 있는 픽셀을 하나씩 접근합니다.
for y in range(0, height):
for × in range(0, width):
# 컬러 이미지의 (x,y)에 있는 픽셀의 b,g,r 채널을 읽습니다.
b = img_color.item(y, x, 0)
g = img_color.item(y, x, 1)
r = img_color.item(y, x, 2)
# (x,y) 위치의 픽셀에 그레이 스케일값이 저장됩니다.
# 평균값 사용하는 경우
# gray = int((r + g + b) / 3.0)
# BT.709에 명시된 비율 사용하는 경우
gray = int(r*0.2126 + g*0.7152 + b*0.0722)
img_gray.itemset(y, x, gray)
# 결과 이미지에 컬러를 표시하기 위해 # 컬러 이미지로 변환합니다.
img_result = cv.cvtColor(img_gray, cv.COLOR_GRAY2BGR)
# y범위가 150~200, x범위가 200~250인 영역의 픽셀을 # 초록색 픽셀로 변경합니다.
for y in range(150, 201):
for × in range(200, 251):
img_result.itemset(y, x, 0, 0) # b
img_result.itemset(y, x, 1, 255) # g
img_result.itemset(y, x, 2, 0) # r
cv.imshow('color', img_color)
cv.imshow('result', img_result)
cv.waitKey(0)
cv.destroyAllWindows()