공부 노트/연구회

[연구회/OpenCV] 원본 사진 흑백 사진으로 출력하기

미로910 2025. 9. 15. 22:35

🟡
B-G-R 더한 후 나누기 3을 해주면 gray 값이 나옴
--------------------------------------------------------------------
1. B-G-R 순회하며 더함
2. /3 해서 gray 값 획득
3. 다시 B-G-R 돌며 값 나눠줌

다시
1. B-G-R 순회하며 더함
2. /3 해서 gray 값 획득
3 다시 B-G-R 돌며 값 나눠줌 

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

using namespace cv;
using namespace std;

int main(int ac, char** av)
{
    Mat img = imread("mario.jpg", IMREAD_ANYCOLOR);
    Mat res = imread("mario.jpg", IMREAD_ANYCOLOR);

    uchar* res_data = res.data;

    int light = -50; // 밝기 조절값

    for (int row = 0; row < res.rows; row++) {      // 첫 번째 순회
        for (int col = 0; col < res.cols; col++) {
            int index = row * img.cols * 3 + col * 3; // BGR → 3칸 차지

            int gray = 0; // gray 값 저장 변수

            // 1. BGR 순회하며 값 더하고 밝기 보정
            for (int i = 0; i < 3; i++) {
                int value = res_data[index + i] + light;

                if (value > 255) value = 255;
                else if (value < 0) value = 0;

                gray += value; // 더하기
            }

            // 2. 나누기 3 해서 gray 값 획득
            gray /= 3;

            // 3. 다시 BGR 순회하며 gray 값 나눠줌 (흑백화)
            for (int i = 0; i < 3; i++) {
                res_data[index + i] = gray;
            }
        }
    }

    imshow("mario", img);
    imshow("res", res);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

문제점!!

캐릭터만 흑백으로 해야 되는데 사진 전체를 흑백으로 함


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

using namespace cv;
using namespace std;

int main(int ac, char** av)
{
    /*
    img에서 캐릭터 찾아 흑백으로 만드는 것
    - 만약 흰색이 아니라면 -> 흑백
        - 평균 값을 구하고 평균값을 res의 픽셀 위치에 BGR 값으로 똑같이 덮어 씌움 (반복)
    */


    // Mat(행렬), imread -> 이미지 파일 읽어오기
    Mat img = imread("mario3.png", IMREAD_ANYCOLOR);
    Mat res = imread("mario3.png", IMREAD_ANYCOLOR);

    // 이미지의 실제 픽셀 데이터에 직접 접근 / uchar* -> 포인터 도구
    uchar* img_data = img.data;
    uchar* res_data = res.data;

    int light = 0; 

    // 모든 픽셀을 하나씩 순회하는 반복문
    for (int row = 0; row < res.rows; row++) {
        for (int col = 0; col < res.cols; col++) {
            int index = row * img.cols * 3 + col * 3;

            // 원본 픽셀의 BGR 값을 가져오기
            uchar b = img_data[index];
            uchar g = img_data[index + 1];
            uchar r = img_data[index + 2];

            
            // 만약 현재 픽셀이 흰색이 아니라면 
            if (!(b == 255 && g == 255 && r == 255)) {
              

                // 평균값 계산
                int gray = 0; 

                
                for (int i = 0; i < 3; i++) {
                    int value = res_data[index + i] + light;
                    if (value > 255) value = 255;
                    else if (value < 0) value = 0;
                    gray += value;
                }

                
                gray /= 3;

                // BGR -> gray 값을 적용
                for (int i = 0; i < 3; i++) {
                    res_data[index + i] = gray;
                }
            }
        
        }
    }

    imshow("mario", img);
    imshow("res", res);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

해결!!

1. mario 배경을 투명 말고 흰색으로 사용

2. 어떤 픽셀을 흑백으로 바꿀 것인가'에 대한 기준(조건)을 추가

 

'공부 노트 > 연구회' 카테고리의 다른 글

[개념] OpenCV란?  (1) 2025.09.15
[기초] class 개념  (1) 2025.09.15