오늘은 그림을 아래와 같이 바꾸는 방법에 대해 소개해볼까 합니다.
아래 코드는 pixel 함수로 symbol[4] 배열에 총 4가지의 기호로 그림을 표현주었다. (아스크 코드 번호 참조)
또한, 그림에 기호를 넣기 위해 아래와 같이 설정을 해주었다.
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0);
현재 mask는 10x10으로 설정하였으며 해당 밝기 값을 다 더해서 /100(mask*mask size) /255(RGB 값) 나누기를 하면 최종적으로 0 ~ 1 사이 값이 나오게 된다. 이때 0~1 사이를 4 범위로 나눠주어서 (4개의 기호로 표현해주기 때문에) cvPutText(cpimg, text, cvPoint(i,j), &font, CV_RGB(0, 0, 0)); 에 넣어준다.
void pixel(IplImage *img, IplImage *cpimg)
{
int mask = 10;
char symbol[4] = {35, 47, 42, 46};
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0);
for (int i = 0; i < img->width-mask; i += mask)
{
for (int j = 0; j < img->height - mask; j += mask)
{
double bright = 0.0;
for (int mx = i; mx < i + mask; mx++)
{
for (int my = j; my< j + mask; my++)
{
auto c = cvGet2D(img, my, mx);
bright += (c.val[0] + c.val[1] + c.val[2]) / 3.0;
}
}
bright /= (mask*mask); //0~255
int index = (int)((bright / 255.0) * 4);
char text[2] = { symbol[index], NULL };
cvPutText(cpimg, text, cvPoint(i,j), &font, CV_RGB(0, 0, 0));
}
}
}
아래 코드는 다른 openCV 관련 글에서도 계속 써듯이 원본 이미지와 바뀐 이미지를 붙여서 비교하기 위한 함수이다. 원본 이미지의 width 값을 2배하여서 한쪽에는 원본 이미지 픽셀을 복사 다른 한 쪽에는 바뀐 이미지 픽셀을 복사하여 한 window 창에 보여줄 수 있게 한다.
IplImage *merge(IplImage *img, IplImage *cpimg)
{
IplImage *bimg = cvCreateImage(cvSize(img->width * 2, img->height), 8, 3);
for (int i = 0; i < img->width; i++)
{
for (int j = 0; j < img->height; j++)
{
auto color1 = cvGet2D(img, j, i);
auto color2 = cvGet2D(cpimg, j, i);
cvSet2D(bimg, j, i, color1);
cvSet2D(bimg, j, img->width + i, color2);
}
}
return bimg;
}
위에 함수들을 호출하는 main이다.
int main(void)
{
IplImage *img = cvLoadImage("img//cat3.jpg");
IplImage *cpimg = cvCreateImage(cvGetSize(img), 8, 3);
cvSet(cpimg, CV_RGB(255, 255, 255)); //배경 흰색으로 바꿔주기
pixel(img, cpimg);
auto bimg = merge(img, cpimg);
cvShowImage("My Window", bimg);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage(&img);
}
아래는 풀 코드이다.
#include <stdio.h>
#include "opencv2/opencv.hpp"
void pixel(IplImage *img, IplImage *cpimg)
{
int mask = 10;
char symbol[4] = {35, 47, 42, 46};
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0);
for (int i = 0; i < img->width-mask; i += mask)
{
for (int j = 0; j < img->height - mask; j += mask)
{
double bright = 0.0;
for (int mx = i; mx < i + mask; mx++)
{
for (int my = j; my< j + mask; my++)
{
auto c = cvGet2D(img, my, mx);
bright += (c.val[0] + c.val[1] + c.val[2]) / 3.0;
}
}
bright /= (mask*mask); //0~255
int index = (int)((bright / 255.0) * 4);
char text[2] = { symbol[index], NULL };
cvPutText(cpimg, text, cvPoint(i,j), &font, CV_RGB(0, 0, 0));
}
}
}
IplImage *merge(IplImage *img, IplImage *cpimg)
{
IplImage *bimg = cvCreateImage(cvSize(img->width * 2, img->height), 8, 3);
for (int i = 0; i < img->width; i++)
{
for (int j = 0; j < img->height; j++)
{
auto color1 = cvGet2D(img, j, i);
auto color2 = cvGet2D(cpimg, j, i);
cvSet2D(bimg, j, i, color1);
cvSet2D(bimg, j, img->width + i, color2);
}
}
return bimg;
}
int main(void)
{
IplImage *img = cvLoadImage("img//cat3.jpg");
IplImage *cpimg = cvCreateImage(cvGetSize(img), 8, 3);
cvSet(cpimg, CV_RGB(255, 255, 255)); //배경 흰색으로 바꿔주기
pixel(img, cpimg);
auto bimg = merge(img, cpimg);
cvShowImage("My Window", bimg);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage(&img);
}
그 밖에 결과 이미지들 :
결과가 귀엽게 잘 나온 것을 확인할 수 있습니다. 다음 글에는 또 다른 새로운 것을 시도해보겠습니다.
문득 이 프로젝트를 하니 이미지를 도트화 시켜 보는 프로젝트도 해보고 싶네요 기회가 되면 다음 번에 시도해서 글을 작성해보겠습니다.
'IT' 카테고리의 다른 글
[openCV / C++] Image Thresholding 이미지 처리하기, 이미지 이진화 (0) | 2021.01.04 |
---|---|
사진 노이즈 제거하기 (gaussian filter, gaussian blur) (0) | 2021.01.04 |
[opencv][C++ ] 가우시안 필터 구현하기 / 사진 노이즈 제거하기 (gaussian filter, gaussian blur) (0) | 2020.12.31 |
[openCV / c++] 사진 반만 흑백으로 만들기 / 사진 밝게 만들기 / 사진 어둡게 만들기 (0) | 2020.12.30 |
[c++/openCV] 비주얼 스튜디오(visual stdio)에 openCV 설치하기 (0) | 2020.12.30 |
댓글