블로그 보관함

2018년 5월 27일 일요일

cv2.morphologyEx

파이썬 OpenCV
 - 11opening,closing,gradient 

* 본 포스팅은 개인 메모입니다 *




Original
아래 사진이 원본이다. 













opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)


Opening
개체 바깥쪽 노이즈 삭제














Closing
사람 개체 내에 잔여물들이 사라진다











Gradient
하나하나 개체의 윤곽선이 다드러난다
사람과 사람 몸에 있던 흔적들
 

Open CV 주요함수

OpenCV에서 주로 사용하는 함수들

자주 쓰는 함수가 잘 정리되어있는것 같아서 
나중에 필요할때 찾아보려 저장.

영상입출력
cvLoadImage영상 읽기IplImage* cvLoadImage( const char* filename, int iscolor = 1);
* isColor 값 종류
#define CV_LOAD_IMAGE_COLOR           1
#define CV_LOAD_IMAGE_GRAYSCALE     0
#define CV_LOAD_IMAGE_UNCHANGED  -1
cvShowImage영상 보기void cvShowImage( const char* name,
                            const CvArr* image );
cvSaveImage영상 저장int cvSaveImage( const char* filename,
                        const CvArr* image );
창 제어
cvNamedWindow창 생성int cvNamedWindow( const char* name,
                               int flags );
cvMoveWindow창 이동void cvMoveWindow( const char* name,
                               int x,
                               int y );
cvDestroyWindow창 파괴void cvDestroyWindow( const char* name );
cvDestroyAllWindows모든 창 파괴void cvDestroyAllWindows();
cvResizeWindow창 크기 조절void cvResizeWindow( const char* name,
                                int width,
                                int height );
영상 조작
cvCreateImage영상 데이터 할당IplImage* cvCreateImage( CvSize size,
                                     int depth,
                                     int channels );
cvReleaseImage할당한 영상 데이터를 해제
구조체를 삭제하고 메모리 반환
void cvReleaseImage( IplImage** image);
cvCloneImage영상 데이터 복제IplImage* cvCloneImage( const IplImage* image );
cvThreshold영상의 이진화 수행하는 함수void cvThreshold(const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type);
매트릭스
cvCreateMat매트릭스 구조체를 만들어주는 함수CvMat* cvCreateMat(int rows, int cols, int type);
cvSetZero매트릭스 모든 항을 0으로 만듬void cvSetZero(CvArr* arr);
cvmSet매트릭스 항에 값을 쉽게 넣을 수 있음CV_INLINE void cvmSet(CvMat* mat, int row, int col, double value);
cvmGet매트릭스 항의 값을 쉽게 얻을 수 있음CV_INLINE void cvmGet(CvMat* mat, int row, int col);
카메라 처리 관련
cvCreateCameraCapture
= cvCaptureFromCAM
CvCapture 구조체 생성하고 그 포인터 반환, 카메라와 구조체 연결 역할CvCapture* cvCreateCameraCapture(int index);
cvGrabFrame카메라에서 입력된 영상 한 프레임 잡음int cvGrabFrame(CvCapture* capture);
cvRetrieveFrame잡은 프레임에서 이미지 얻어냄IplImage* cvRetrieveFrame(CvCapture* capture);
cvQueryFrame카메라에서 한 프레임 잡아와서 이미지 구조체에 넘어줌IplImage* cvQueryFrame(CvCapture* capture);
cvReleaseCaptureCvCapture 구조체의 메모리 반환void cvReleaseCapture(CvCapture** capture);
cvCreateVideoWriter비디오출력기 생성해주는 함수CvVideoWriter* cvCreateVideoWriter(const char* filename, int fourcc, double fps, CvSize frame_size, int is_color CV_DEFAULT(1));
cvWriteFrame비디오 출력기에 이미지 넘겨줌int cvWriteFrame(CvVideoWriter* writer, const IplImage* image);
cvReleaseVideoWriter비디오 출력기 메모리 반환void cvReleaseVideoWriter(CvVideoWriter** writer);
그 외
cvWaitKey키 입력 받을 수 있도록 대기시간 가짐int cvWaitKey(int delay CV_DEFAULT(0));
cvSplit영상의 채널을 각각의 싱글 채널 이미지 구조체에 자동적으로 분리 void cvSplit(const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3);
cvGetReal2D지정한 좌표의 픽셀값 리턴double cvGetReal2D(const CvArr* arr, int idx0, int idx1);
cvSetReal2D이미지 데이터의 어떤 좌표에 값을 넣어줌double cvSetReal2D(const CvArr* arr, int idx0, int idx1);
[출처] OpenCV 주요함수|작성자 윈섬


출처: http://jangjy.tistory.com/18?category=625807 [살다보니..]

cv::Mat Class 사용법

아래 내용은 다크pgmr ( http://darkpgmr.tistory.com/46 ) 님의 블로그에서 복사한 내용입니다.

내용에 내가 필요료 하는 것들 추가로 기록할 예정입니다.

====================================================================================

using namespace cv;

1. 이미지 읽기 & 저장
Mat img_color = imread("sample.jpg"); // color load
Mat img_gray = imread("sample.jpg", 0);// gray load
imwrite("fname.jpg", img);

2. 이미지 생성, 복사, 형변환, 색상변환, roi 설정
int w = 320;// width
int h = 240;// height

// 생성
Mat img(h,w,CV_8UC1);                    //1채널 unsigned char
Mat img(h,w,CV_8UC3);                    //3채널 unsigned char
Mat img = Mat::zeros(h,w,CV_32FC1);//1채널 float
Mat img = Mat::ones(h,w,CV_64FC3);//3채널 double

unsigned char * img_buffer;            // 이미지버퍼 포인터
Mat img(h, w, CV_8UC3, img_buffer);//메모리 공유

// 원소 초기화
Mat img(h,w,CV_8UC1);
img = Scalar(3);                 // img 모든 원소값 3으로 초기화

// 참조, 복사
Mat img2 = img;                 // 메모리 공유
Mat img2 = img.clone(); // 별도 메모리
Mat img2; img.copyTo(img2);//별도 메모리

// 형변환 복사
Mat img1(h,w,CV_32FC1);
Mat img2;
img1.convertTo(img2, CV_8U);

// gray-color 변환
cvtColor(color, gray, CV_BGR2GRAY);
cvtColor(gray, color, CV_GRAY2BGR);

// roi 설정
Rect roi;
Mat sub_img = img(roi);                //메모리공유
Mat sub_img = img(roi).clone();    //별도메모리

3. 영상 크기변경 및 상하좌우 반전
// 크기 변경
Mat dst;
resize(img, dst, Size(new_w,new_h));
resize(img, dst, Size(), 0.5, 0.5);    //scalex, scaley

// 영상 반전(flip)
flip(img, dst, 0);        // vertical flip
flip(img, dst, 1);        // horizontal flip
flip(img, dst, -1);       // vertial & horizontal flip

4. 이미지에 그리기 (drawing)
Rect rc(x,y,w,h);
Scalar color(B,G,R);
int thickness=1;         // line thickness

line(img, Point(x1,y1), Point(x2,y2), color, thickness);

rectangle(img, rc, color, thickness);
rectangle(img, rc.tl(), rc.br(), color, thickness);
rectangle(img, rc, color, CV_FILLED); // filled rectangle

Point center(rc.x+rc.width/2, rc.y+rc.height/2);
Size radius(rc.width/2, rc.height/2);
double rot_deg = 0;     // rotation of ellipse
double s_deg = 0;     // start angle of arc
double e_deg = 360;     // end angle of arc
ellipse(img,center,radius,rot_deg,s_deg,e_deg,color,thickness);
ellipse(img,center,radius,rot_deg,s_deg,e_deg,color,CV_FILLED);

int circle_radius = 10;
circle(img, center, circle_radius, color, thickness);
circle(img, center, circle_radius, color, CV_FILLED);

putText(img, "text", Point(x,y), FONT_HERSHEY_SIMPLEX, 1., color, thickness);
putText(img, "text", Point(x,y), FONT_HERSHEY_DUPLEX, 1., color, thickness);

5. 이미지 디스플레이하기 (display)
namedWindow("name");                                 // auto resized
namedWindow("name",CV_WINDOW_NORMAL); // manual resize

imshow("name", img);
char ch = waitKey();     // 무한 대기
char ch = waitKey(10);    // 10 msec 대기
if(ch == 27) ...             // ESC key
if(ch == 32) ...             // SPACE key

destroyWindow("name");
destroyAllWindows();

6. 웹캠 연결하기
VideoCapture vc(0);
if (!vc.isOpened()) return; // 연결실패
vc.set(CV_CAP_PROP_FRAME_WIDTH, 640);
vc.set(CV_CAP_PROP_FRAME_HEIGHT, 480);

Mat img;
while(1){
vc >> img;
if(img.empty()) break;
imshow("cam",img);
if(waitKey(10)==27) break; //ESC
}
destroyAllWindows();

7. avi 비디오 파일 읽어오기
VideoCapture vc("sample.avi");
if (!vc.isOpened()) return; // 불러오기 실패

Mat img;
while(1){
vc >> img;
if(img.emplty()) break;
imshow("video",img);
if(waitKey(10)==27) break; //ESC
}
destroyAllWindows();

8. avi 비디오 녹화하기
double fps = 15;
int fourcc = CV_FOURCC('X','V','I','D'); // codec
bool isColor = true;

VideoWriter *video = new VideoWriter;
if(!video->open("result.avi", fourcc, fps, Size(img_w, img_h), isColor)){
delete video;
return;
}

Mat img;
while(1){
// ...
*video << img;
// ...
}
delete video;

9. Mat <--> IplImage
Mat --> IplImage
Mat matimg;
IplImage* iplimh;
iplimg = &IplImage(matimg);

IplImage --> Mat

IplImage* iplimg;
Mat matimg;
matimg(iplimg);
  
10. 픽셀 접근법
  Mat image;
  
  // 3 channel Image

  1. for(int j=0; j < image.rows; j++)
  2. {
  3.         for(int i=0; i < image.cols; i++)
  4.         {
  5.                  image.at<Vec3b> (j,i)[0] += 30;
  6.                  image.at<Vec3b> (j,i)[1] += 20;
  7.                  image.at<Vec3b> (j,i)[2] += 20;
  8.         }
  9. }

이때 Vec3b 는 unsigned char 형이다 
b(unsigned char) 외에도 s(short), i(int), f(float), d(double) 형의 벡터가 존재한다.

* 추가사항 *
cv::Mat클래스의 at메소드를 사용한다면 가끔은 성가실 수 있다. 행렬 타입을 알고 있다면 cv::Mat의 템플릿 하위 클래스인 cv::Mat_ 클래스를 사용할 수 있다.

cv::Mat_<uchar> im2 = image;  //im2는 image를 참조
im2(50,100) = 0; // 50행 100열 화소에 접근


출처: http://jangjy.tistory.com/21 [살다보니..]