색 바꾸기
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat img = cv::imread("image/lena.jpg",1);
cv::Mat dst, dst2, dst3;
cv::cvtColor(img, dst, cv::COLOR_BGR2GRAY);
cv::cvtColor(img, dst2, cv::COLOR_BGR2HSV);
cv::cvtColor(img, dst3, cv::COLOR_BGR2YUV);
cv::imshow("original", img);
cv::imshow("GRAY", dst);
cv::imshow("HSV", dst2);
cv::imshow("YUV", dst3);
cv::waitKey(0);
cv::destroyAllWindows();
}
imshow 는 기본적으로 BGR 채널을 가정함으로 HSV 의 경우 그대로 1대1대응이 되버린다. HSV ,YUV 를 imshow로 보는 것은 적합하지않다.
split merge
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat img = cv::imread("image/lena.jpg",1);
cv::resize(img, img, cv::Size(200, 200 * img.rows / img.cols));
cv::imshow("org", img);
std::vector<cv::Mat> channel;
cv::split(img, channel);
char wname[10];
for (int i = 0; i < img.channels(); i++)
{
sprintf_s(wname, "ch%d", i);
cv::imshow(wname, channel[i]);
}
cv::Mat merged;
channel[0] = channel[0] / 2;
channel[1] = channel[1] / 2;
cv::merge(channel, merged);
cv::imshow("mrg", merged);
cv::waitKey(0);
cv::destroyAllWindows();
}
Ch0 = Blue , Ch1 = green , Ch2= Red 이 나타나야 하지만 single channel임으로 grayscale로 나오는것이다. merge 할때는 red만 그대로 합쳤으므로 원본보다 좀더 붉게 된다.
ROI(region of interest)
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat img = cv::imread("image/lena.jpg",1);
cv::Mat sub1(img, cv::Rect(30, 60, 100, 200));
cv::Mat sub2(img, cv::Rect(cv::Point(130, 260), cv::Point(230, 360)));
sub1 = cv::Scalar(0, 255, 0);
sub2 = cv::Scalar(255, 255, 255);
cv::imshow("sub", sub1);
cv::imshow("sub2", sub2);
cv::imshow("org+sub", img);
cv::waitKey(0);
cv::destroyAllWindows();
}
sub, sub2 ,org는 원 이미지와 데이터를 공유한다(3중 하나라도 바뀌면 같이 싹다 바뀜). 나중에 image processing을 할때 load를 줄여줄수있을 것이다.
Blurring
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat img = cv::imread("image/lena.jpg", 1);
std::vector<cv::Mat> blurred;
for (std::size_t i = 0; i < 4; i++)
{
cv::Mat temp;
blurred.push_back(temp);
}
cv::imshow("origin", img);
cv::blur(img, blurred[0], cv::Size(5, 5));
cv::GaussianBlur(img, blurred[1], cv::Size(5, 5), 0, 0);
cv::medianBlur(img, blurred[2], 5);
cv::bilateralFilter(img, blurred[3], 5,5 * 2, 5 / 2);
cv::imshow("blur", blurred[0]);
cv::imshow("Gaussian", blurred[1]);
cv::imshow("median", blurred[2]);
cv::imshow("bilateral", blurred[3]);
cv::waitKey(0);
cv::destroyAllWindows();
}
조금씩 차이를 보인다.
Size == Defines the size of the kernel to be used ( of width w pixels and height h pixels)
median = size안의 픽셀중 중간값으로
bilteral = 가우시안을 쓰고 경계선은 그대로 놔둠
Theshold
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat img = cv::imread("image/lena.jpg", 1);
std::vector<cv::Mat> blurred;
for (std::size_t i = 0; i < 4; i++)
{
cv::Mat temp;
blurred.push_back(temp);
}
cv::imshow("origin", img);
cv::threshold(img, blurred[0], 120, 255,cv::THRESH_BINARY);
cv::threshold(img, blurred[1], 140, 255, cv::THRESH_BINARY);
cv::threshold(img, blurred[2], 160, 255, cv::THRESH_BINARY);
cv::threshold(img, blurred[3], 180, 255, cv::THRESH_BINARY);
cv::imshow("120", blurred[0]);
cv::imshow("140", blurred[1]);
cv::imshow("160", blurred[2]);
cv::imshow("180", blurred[3]);
cv::waitKey(0);
cv::destroyAllWindows();
}
type 중 OTSU 는 blur를 해준다음에 해주면 좋다
쌀알의 이미지 같이 뭔가 분리할게 많은 경우 adaptive threshold를 쓰는게 좋다.
팽창과 침식
글자안에 까만 점이있을 경우 팽창을 해주면 된다. 커널안에 아주 소수의 픽셀만 검은색이 될테니 그것을 하얀색으로 바꿔버리고 글씨를 크게만듬. 그후 다시 원래사이즈로 돌리기위한 침식
글자 밖에 배경에 하얀점이 있을 경우 침식을 해주면된다. 커널안에 모두가 1이 이어야만 1이되고 아닐시 0으로 바꿔버리기 때문이다. 후에 다시 팽창을 해준다.
HoughLineP 직선검출
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat img_origin = cv::imread("image/lena.jpg", 1);
cv::Mat img;
cv::cvtColor(img_origin, img, cv::COLOR_BGR2GRAY);
cv::Mat edge;
cv::Canny(img, edge, 80, 200, 3);
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(edge, lines, 1, (CV_PI / 180), 30, 50, 10);
for (size_t i = 0; i < lines.size(); i++)
{
cv::line(img, cv::Point(lines[i][0], lines[i][1]),cv::Point(lines[i][2], lines[i][3]),cv::Scalar(0,0,255),1);
}
cv::imshow("edge", edge);
cv::imshow("LInes", img);
cv::waitKey(0);
cv::destroyAllWindows();
}
이용방법
1. 그레이스케일로 변경 2. Cannyedge로 엣지 찾아냄 3. 왼쪽 edge들 중에 threshold를 넘는것을 vec4i 형태로담음 4. 그것들을 선으로 원본(그레이스케일) 에 그려줌.
윤곽선 검출 및 그리기
#include <iostream>
#include<opencv2\opencv.hpp>
int main()
{
cv::Mat src = cv::imread("image/lena.jpg", 1);
cv::Mat canny;
cv::Canny(src, canny, 30, 60);
cv::dilate(canny, canny, cv::Mat(), cv::Point(-1, -1), 1);
std::vector < std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(canny, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
cv::Mat result = src.clone();
for (size_t i = 0; i < contours.size(); i++)
{
cv::Scalar color(rand() % 256, rand() % 256, rand() % 256);
cv::drawContours(result, contours, i, color, -1);
}
cv::imshow("src", src);
cv::imshow("Canny", canny);
cv::imshow("result", result);
cv::waitKey(0);
cv::destroyAllWindows();
}
canny 를 통해 edge를 찾아주고 dilate 를 통해 듬성듬성한 edge를 연결해준다.
drawContours 에 edge -1 해주면 해당 contour를 주어진 색깔로 채워넣는것이다.
다각형으로 근사화 (findcontour 다음에 써주면됨)
std::vector<std::vector<cv::Point>> poly;
poly.resize(contours.size());
for (int i = 0; i < contours.size(); i++)
{
cv::approxPolyDP(contours[i], poly[i], 15, true);
}
일종의 smoothing funciton 처럼 작용한다. 15가 엡실론 값인데 크면 클수록 smooth해진다
'자율주행 > ROS python (xytron 강의)' 카테고리의 다른 글
line_find.py 주어진 영상에서 차선 찾기 (0) | 2021.01.22 |
---|---|
Rosbag file을 통해 비디오생성 (0) | 2021.01.19 |
8자 주행 ,ultrasonic 내 코드 정리 (0) | 2021.01.14 |
8자주행 odom coverter 과제 답안 (0) | 2021.01.12 |
자이카 ROS 패키지 (0) | 2021.01.07 |