Iterator란

Iterator는 컨테이너의 원소들을 순회 할 수 있는 객체


반복자는 컨테이너의 특정 위치를 가리킴

반복자는 Pointer와 같이 연산자를 사용할 수 있는데 pointer와 비슷

 

operator *         :     현재 가리키고 있는 위치 값

operator ++      :     다음 원소

operator --        :     이전 원소

operator != , == :      두 반복자가 같은 위치를 가리키고 있는지

operator =         :     반복자를 할당합니다.

 

가만히 보면 pointer와 비슷해 보인다.. 좀 다르다고 할 수 있는건 복잡한 컨테이너를 순회할 수 있는 스마트포인터라는 것입니다. 나중에 예제로 보겠지만 컨테이너::iterator 로 지정해주면 지정한 컨테이너 타입에 맞춰 움직이다가 iterator 알아서 메모리 관리가 됩니다. 지정한 자료의 삭제 같은 것이 필요 없다는 것이죠.

 

컨테이너에 보면 가지고 있는 원소를 순회하기 위해 공통 멤버 함수가 있습니다. 간단하게

begin() 과 end()을 보도록 하죠.


 


여기꽤 중요한 것이 있는데 end()는 마지막을 하나 지난 위치 입니다.  이걸 half-open range(반 개방 범위)라고 하는데요 

2가지 장점이 있습니다. 꼭 장점만 있지는 않습니다.. 잘못처리 하면 문제일으킬 소지를 다분히 가지고 있습니다.

 

  1.원소를 순회하는 루프를 간단히 할 수 있다. end()에 다다르지 않았다면 계속해서 루프를 돌면 된다.

  2.빈 범위에 대해서 특별한 처리를 할 필요가 없다. 빈 컨테이너에 대해서 begin()과 end()는 동일하다.

 

이런 특성 때문에 for 문을 작성할 때


for(vector<char>::iterator a = c.begin ; a != c.end() ; ++a)


와 같은 식으로!= 로 비교하고 ++a 를 사용합니다. end() 같지 않을 때 까지 계속 이동하면서 증가를 합니다.

증가 연산은 전위(prefix operator)를 사용합니다. 

이유는 class에서 증가연산자를 overloading 해 보셨다면 왜인지 아실것 같은데 후위(postfix)는 반복자의 이전값을 반환하기 때문에 임시로 객체가 생깁니다.

아무래도 전위 증가/감소가 성능이 좋겠죠. 후위를 써도 괜찮긴 하지만 사용하지 마세요.

 

그리고 iterator은 두 가지가 있는데

container::iterator   원소들을 읽기/쓰기 가능합니다.

container::const_iterator   읽기 전용으로 순회합니다


출처 : http://egloos.zum.com/ErinSyndrome/v/913685

'Programming > openCV' 카테고리의 다른 글

vector에 접근하는 두가지 방법  (0) 2017.04.11
13. Hough Circles  (0) 2017.04.04
12. Templet Matching  (0) 2017.04.04
11. Emboss, sketch, 수채화  (0) 2017.04.04
10. 마우스로 영역을 지정한 부분만 엣지 검출  (0) 2017.04.04

방법

1. 템플릿 매칭방법을 선택하고, 매칭을 시작한다.

2. 방법에따라 최대값을 찾을 것인지, 최소값을 찾을 것인지 정한다.

3. 그 부분에 사각형을 그린다.


코드

#include <opencv2/opencv.hpp>

#include <opencv2/highgui.hpp>


using namespace cv;

using namespace std;

int main()

{

Mat srcImage = imread("image4/alphabet.bmp", CV_LOAD_IMAGE_GRAYSCALE);

if (srcImage.empty())

return -1;


Mat tImage1 = imread("image4/A.bmp", CV_LOAD_IMAGE_GRAYSCALE);

Mat tImage2 = imread("image4/S.bmp", CV_LOAD_IMAGE_GRAYSCALE);

Mat tImage3 = imread("image4/b.bmp", CV_LOAD_IMAGE_GRAYSCALE);

Mat tImage4 = imread("image4/m.bmp", CV_LOAD_IMAGE_GRAYSCALE);


Mat dstImage;

cvtColor(srcImage, dstImage, COLOR_GRAY2BGR);


double minVal, maxVal;

Point minLoc, maxLoc;

Mat result;


// 제곱차 매칭 방법(TM_SQDIFF) 어두운곳이 매칭지점

matchTemplate(srcImage, tImage1, result, TM_SQDIFF);

imshow("TM_SQDIFF", result);

//비교한 MAT중에서 가장 큰 값을 찾는다.

minMaxLoc(result, &minVal, NULL, &minLoc, NULL);

rectangle(dstImage, minLoc,

Point(minLoc.x + tImage1.cols, minLoc.y + tImage1.rows), Scalar(255, 0, 0), 2); //blue


// 정규화된 제곱차 매칭 방법(TM_SQDIFF_NORMED) 어두운곳이 매칭지점

matchTemplate(srcImage, tImage2, result, TM_SQDIFF_NORMED);

imshow("TM_SQDIFF_NORMED", result);

minMaxLoc(result, &minVal, NULL, &minLoc, NULL);

rectangle(dstImage, minLoc,

Point(minLoc.x + tImage2.cols, minLoc.y + tImage2.rows), Scalar(0, 255, 0), 2); //green


// 정규화된 상관관계 방법(TM_CCORR_NORMED) 밝은곳이 매칭지점

matchTemplate(srcImage, tImage3, result, TM_CCORR_NORMED);

imshow("TM_CCORR_NORMED", result);


minMaxLoc(result, NULL, &maxVal, NULL, &maxLoc);

rectangle(dstImage, maxLoc,

Point(maxLoc.x + tImage3.cols, maxLoc.y + tImage3.rows), Scalar(0, 0, 255), 2); //red


// 정규화된 상관계수 방법(TM_CCOEFF_NORMED) 밝은곳이 매칭지점

matchTemplate(srcImage, tImage4, result, TM_CCOEFF_NORMED);

imshow("TM_CCOEFF_NORMED", result);

minMaxLoc(result, NULL, &maxVal, NULL, &maxLoc);

rectangle(dstImage, maxLoc,

Point(maxLoc.x + tImage4.cols, maxLoc.y + tImage4.rows), Scalar(255, 0, 255), 2);//puple


imshow("dstImage", dstImage);

waitKey();

return 0;

}



image안에서 x, y로 한칸씩 이동하면서 템플릿을 겹쳐 놓고 각 셀의 차이나 곱의 합을 계산해서 result배열을 만들어서 돌려 준다. 이때 image의 크기는 템플릿의 크기보다 커야 하고 계산 방식은 method로 정해진다.

  • CV_TM_SQDIFF -- 각 픽셀의 제곱의 차이
R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2
  • CV_TM_SQDIFF_NORMED  -- CV_TM_SQDIFF / sqrt(각 픽셀의 제곱의 곱)

R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}

  • CV_TM_CCORR -- 각 픽셀의 곱의 합 (교차 상관)
R(x,y)= \sum _{x',y'} (T(x',y')  \cdot I(x+x',y+y'))
  • CV_TM_CCORR_NORMED -- CV_TM_CCORR / sqrt(각 픽셀의 제곱의 곱)
R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}


  • CV_TM_CCOEFF -- 상관계수
R(x,y)= \sum _{x',y'} (T'(x',y')  \cdot I(x+x',y+y'))
  • CV_TM_CCOEFF_NORMED -- CV_TM_CCOEFF / sqrt(각 픽셀의 제곱의 곱)
NCC- 빠른 정상화 간 상관관계

R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }


구현 결과



'Programming > openCV' 카테고리의 다른 글

13. Hough Circles  (0) 2017.04.04
iterator의 개념  (0) 2017.04.04
11. Emboss, sketch, 수채화  (0) 2017.04.04
10. 마우스로 영역을 지정한 부분만 엣지 검출  (0) 2017.04.04
9. sobel Filter / Canny Edge  (0) 2017.04.04

void emboss(Mat& f)

{

Mat mask(3, 3, CV_32F, Scalar(0)), res;

mask.at<float>(0, 0) = -1.0;

mask.at<float>(2, 2) = 1.0;


filter2D(f, res, CV_16S, mask);

res.convertTo(res, CV_8U, 1, 128);


namedWindow("엠보싱"); imshow("엠보싱", res);

}


void waterColor(Mat& f)

{

#define dsize 7

#define sigma 32

int iterate = 20;

Mat t1 = f.clone(), t2;

for (int i = 0; i<iterate; i++)

if (i % 2 == 0) bilateralFilter(t1, t2, dsize, sigma, sigma);

else bilateralFilter(t2, t1, dsize, sigma, sigma);


namedWindow("수채화");

if (iterate % 2 == 0) imshow("수채화", t1);

else imshow("수채화", t2);

}


void sketch(Mat& f)

{

Mat gray, edge, display;

int thres = 5;


cvtColor(f, gray, CV_BGR2GRAY);

blur(gray, gray, Size(3, 3));

Canny(gray, edge, thres, thres*2.5, 3);


display.create(f.size(), f.type());

display = Scalar::all(128);

f.copyTo(display, edge);


namedWindow("스케치"); imshow("스케치", display);

}



void onTrackbar(int thres, void* gray)

{

Mat* image = (Mat*)gray;

Mat edge, display;


Canny(*image, edge, thres, thres*3, 3);

display.create(input.size(), input.type());

display = Scalar::all(128);

input.copyTo(display, edge);


imshow("스케치 농도", display);

}


void sketchByTrackbar(Mat& input)

{

int pos = 0;

Mat gray;

cvtColor(input, gray, CV_BGR2GRAY);

blur(gray, gray, Size(3, 3));


namedWindow("스케치 농도");

createTrackbar("임계값", "스케치 농도", &pos, 200, onTrackbar, &gray);

setTrackbarPos("임계값", "스케치 농도", pos);


waitKey(1);

}



Track Bar Call Back 사용하기

createTrackbar("임계값", "스케치 농도", &pos, 200, onTrackbar, &gray);


TrackBar CallBack은 (void *)&Mat 을 넘겨주어야한다.




void Mat::copyTo( OutputArray m, InputArray mask ) const

기존에 사용한 단순 복사에서 마스크에 해당하는 파라미터를 추가해주어 복사해온다. 마스크의 특정 픽셀의 값을 확인하여 해당 지점의 값이 0이 아니라면 그에 대응되는 지점의 값을 복사한다.


코드

#include <opencv2/opencv.hpp>

#include <opencv2/highgui.hpp>


using namespace cv;

using namespace std;



bool ldown = false, lup = false;

Mat img, gray_img;

Point corner1, corner2;

Rect box;


void Canny_edge(Mat img);


static void mouse_callback(int event, int x, int y, int, void* param) {


if (event == EVENT_LBUTTONDOWN) {

ldown = true;

corner1.x = x;

corner1.y = y;

}


if (event == EVENT_LBUTTONUP) {

if (abs(x - corner1.x) > 20 && abs(y - corner1.y) > 20) {

lup = true;

corner2.x = x;

corner2.y = y;

}

else {

ldown = false;

}

}


if (ldown == true && lup == false) {

Point pt;

pt.x = x;

pt.y = y;


Mat locale_img = img.clone();


rectangle(locale_img, corner1, pt, Scalar(255, 0, 0));

imshow("Original IMG", locale_img);

}


if (ldown == true && lup == true) {

box.width = abs(corner1.x - corner2.x);

box.height = abs(corner1.y - corner2.y);


box.x = min(corner1.x, corner2.x);

box.y = min(corner1.y, corner2.y);


Mat crop(gray_img, box);

Canny_edge(crop);


ldown = false; lup = false;

}

}


void Canny_edge(Mat img) {

Mat contours;

Canny(img, contours, 50, 100);

imshow("Canny_edge", contours);


Mat contoursInv;

threshold(contours, contoursInv, 128, 255, THRESH_BINARY_INV);

imshow("Canny_edge_INV", contoursInv);

}


int main(int args, char *argv[]) {


img = imread("image/flower.jpg", CV_LOAD_IMAGE_COLOR);;

if (!img.data) {

cout << "Image Can't Load" << endl;

return -1;

}


cvtColor(img, gray_img, CV_BGR2GRAY);

imshow("Gray_img", gray_img);


namedWindow("Original IMG");

imshow("Original IMG", img);

setMouseCallback("Original IMG", mouse_callback);

waitKey(0);

}


결과값


코드

#include "opencv2/opencv.hpp"  

#include <opencv/cv.h>

#include <iostream>


using namespace cv;

using namespace std;


int main() {


Mat image = imread("image/food.jpg", CV_LOAD_IMAGE_COLOR);



namedWindow("video", CV_WINDOW_AUTOSIZE);

namedWindow("Canny", CV_WINDOW_AUTOSIZE);

namedWindow("Sobel", CV_WINDOW_AUTOSIZE);



// Original Image to Gray Image

Mat gray;

cvtColor(image, gray, CV_BGR2GRAY);


// Sobel Filter

Mat sobelX;

Mat sobelY;

Sobel(gray, sobelX, CV_8U, 1, 0);

Sobel(gray, sobelY, CV_8U, 0, 1);

Mat imageSobel;

imageSobel = abs(sobelX) + abs(sobelY);

Mat imageCanny;

Canny(gray, imageCanny, 50, 200);


imshow("video", image);

imshow("Canny", imageCanny);

imshow("Sobel", imageSobel);


waitKey(0);

}


결과값






결과값



코드

#include "opencv2/opencv.hpp"  

#include <iostream>  


using namespace cv;

using namespace std;


int main(){


VideoCapture capture("image/Wildlife.wmv");


int fps = capture.get(CAP_PROP_FPS);

int ex = static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));


char EXT[] = {

(char)(ex & 0XFF),

(char)((ex & 0XFF00) >> 8),

(char)((ex & 0XFF0000) >> 16),

(char)((ex & 0XFF000000) >> 24),

0

};



int hei = capture.get(CAP_PROP_FRAME_HEIGHT);

int wid = capture.get(CAP_PROP_FRAME_WIDTH);



printf("fourcc = %s \n", EXT);

printf("size = [%d x %d]\n", wid, hei);

printf("fps = %d\n", fps);


Mat frame;

Mat frameCanny;

//namedWindow("input", 1);



Size size = Size((int)capture.get(CAP_PROP_FRAME_WIDTH),

(int)capture.get(CAP_PROP_FRAME_HEIGHT));



VideoWriter outputVideo;

outputVideo.open("ouput.avi", CV_FOURCC('D', 'I', 'B', ' '), fps, size, true);

if (!outputVideo.isOpened())

{

cout << "동영상을 저장하기 위한 초기화 작업 중 에러 발생" << endl;

return 1;

}



while (1)

{

capture >> frame;

if (!frame.empty()) {

Canny(frame, frameCanny, 80, 150, 3);


imshow("video", frame);

imshow("Canny", frameCanny);


outputVideo << frameCanny;

outputVideo.write(frameCanny);

if (waitKey(30) == 'q') break;

}

}



return 0;

}



'Programming > openCV' 카테고리의 다른 글

10. 마우스로 영역을 지정한 부분만 엣지 검출  (0) 2017.04.04
9. sobel Filter / Canny Edge  (0) 2017.04.04
7. 비디오 출력하기  (0) 2017.04.04
6. 디졸브와 트랙바  (0) 2017.04.04
5. 영상 디졸브  (0) 2017.04.04

#include <opencv2/imgcodecs.hpp>  

#include <opencv2/imgproc.hpp>  

#include <opencv2/highgui.hpp>  

#include <iostream>  


using namespace cv;

using namespace std;


int main()

{

VideoCapture cap1("image/Wildlife.wmv");


Mat frame1;

namedWindow("video", 1);


while(true){

cap1 >> frame1;

imshow("video", frame1);

if (waitKey(30) == 'q') break;  

}


return 0;

}

#include<iostream>

#include<opencv2\core.hpp>

#include<opencv\cv.h>

#include<opencv2\highgui.hpp>

#include<opencv2\imgproc.hpp>


using namespace cv;

using namespace std;


int main() {


Mat src1 = imread("image/bike.jpg", CV_LOAD_IMAGE_COLOR);

Mat src2 = imread("image/holse.jpg", CV_LOAD_IMAGE_COLOR);

Mat dst;


int value;


resize(src1, src1, Size(src2.cols, src2.rows), 0, 0, 1);


namedWindow("Dissolve Image", CV_WINDOW_AUTOSIZE);


createTrackbar("혼합계수", "Dissolve Image", &value, 100);

setTrackbarPos("혼합계수", "Dissolve Image", 50);


while (true) {


value = getTrackbarPos("혼합계수", "Dissolve Image");

//계수값은 0 ~ 100이고 alpha는 0 ~ 1 값이므로 아래와 같이 처리해 줘야한다.

double alpha = (value / 100) + ((value % 100) * 0.01);

double beta = 1 - alpha;


addWeighted(src1, alpha , src2, beta, 0.0, dst);

imshow("Dissolve Image", dst);


if (waitKey(1) == 'q') break;

}


waitKey(0);

}



+ Recent posts