박민혀기
CELLON Kart Source Code 1.3.2V (2023.08.02) 본문
CELLON Kart(Tracking)/Source Code
CELLON Kart Source Code 1.3.2V (2023.08.02)
박민혀기 2023. 8. 2. 23:40Update Feature
- AdaptiveHSV 적용
- Size, HSV의 Balance 비교
Next Develop
- AutoFocus 카메라 사용시 샤프닝 적용
- AdaptiveHSV balance(meanHSV & This_HSV) 7:3
Laptop 개발로 인한 pragma 주의
해상도의 일정 크기(가로세로 각각20%) 이상일 경우 추출
dis_HSV값 (40, 40, 40) -> (20, 20, 60)로 변경
잠깐 테스트 해봤지만 이전보다 안정적으로 작동하는 것으로 보임.
더 많은 DB 필요!
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "opencv_world453.lib")
#pragma comment(lib, "opencv_world453d.lib")
#include <iostream>
#include <cmath>
#include <opencv2/opencv.hpp>
#define COUNT_CONTOUR 5 //MIN_CONTOUR >= COUNT_CONTOUR
using namespace std;
using namespace cv;
Mat frame;
Scalar meanHSV = Scalar(0, 0, 0);
bool comparePointVectors(const vector<Point>& a, const vector<Point>& b) {
return a.size() > b.size();
}
vector<vector<Point>> SortingArea(vector<vector<Point>> SortingContours) {
sort(SortingContours.begin(), SortingContours.end(), comparePointVectors);
return SortingContours;
}
Scalar pixels_avg(vector<Scalar> pixels) {
Scalar avgHSV(0, 0, 0);
for (int i = 0; i < pixels.size(); i++)
avgHSV += pixels[i];
avgHSV /= static_cast<float>(pixels.size());
return avgHSV;
}
int Close_HSV(vector<Scalar> Compare_HSV_List) {
int Close_HSV_Index = 0;
int Close_HSV_Dis, Close_HSV_Dis_List;
Scalar Close_HSV = Compare_HSV_List[0];
Scalar Close_HSV_Min, Close_HSV_Min_List, Close_HSV_List;
for (int i = 1; i < Compare_HSV_List.size(); i++) {
Close_HSV_Min = meanHSV - Close_HSV;
Close_HSV_Dis = abs(Close_HSV_Min[0]) + abs(Close_HSV_Min[1]) + abs(Close_HSV_Min[2]);
Close_HSV_Min_List = meanHSV - Compare_HSV_List[i];
Close_HSV_Dis_List = abs(Close_HSV_Min_List[0]) + abs(Close_HSV_Min_List[1]) + abs(Close_HSV_Min_List[2]);
if (Close_HSV_Dis > Close_HSV_Dis_List) {
Close_HSV = Compare_HSV_List[i];
Close_HSV_Index = i;
}
else continue;
}
return Close_HSV_Index;
}
void AdaptiveHSVUpdate(vector<vector<Point>> Contours, int Close_Index) {
Mat hsv_frame;
cvtColor(frame, hsv_frame, COLOR_BGR2HSV);
Mat contours_mask = Mat::zeros(frame.size(), CV_8UC1);
drawContours(contours_mask, Contours, Close_Index, Scalar(255), -1);
imshow("contours_mask", contours_mask);
vector<Scalar> pixels;
for (int y = 0; y < contours_mask.rows; y++) {
for (int x = 0; x < contours_mask.cols; x++) {
if (contours_mask.at<uchar>(y, x) == 255) {
pixels.push_back(hsv_frame.at<Vec3b>(y, x));
}
}
}
Scalar This_HSV = pixels_avg(pixels);
meanHSV = (meanHSV + This_HSV) / 2;
}
void HSV_Process(Scalar lowerHSV, Scalar upperHSV, Size resol) {
Mat hsv_frame, mask;
vector<Scalar> HSV_List;
cvtColor(frame, hsv_frame, COLOR_BGR2HSV);
inRange(hsv_frame, lowerHSV, upperHSV, mask);
imshow("mask", mask);
vector<vector<Point>> contours;
findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
contours = SortingArea(contours);
for (int i = 0; i < COUNT_CONTOUR; i++) {
Rect Max_BoundRect = boundingRect(contours[i]);
if (Max_BoundRect.width < resol.width / 5 || Max_BoundRect.height < resol.height / 5) continue;
Mat contours_mask = Mat::zeros(frame.size(), CV_8UC1);
drawContours(contours_mask, contours, i, Scalar(255), -1);
//mean으로 가능은 할 듯
vector<Scalar> pixels;
for (int y = 0; y < contours_mask.rows; y++) {
for (int x = 0; x < contours_mask.cols; x++) {
if (contours_mask.at<uchar>(y, x) == 255) {
pixels.push_back(hsv_frame.at<Vec3b>(y, x));
}
}
}
HSV_List.push_back(pixels_avg(pixels));
}
if (HSV_List.size() > 0) {
int Close_Contour_Index = Close_HSV(HSV_List);
Rect boundRect = boundingRect(contours[Close_Contour_Index]);
drawContours(frame, contours, Close_Contour_Index, cv::Scalar(0, 255, 255), 1);
rectangle(frame, boundRect, Scalar(0, 255, 0), 2);
AdaptiveHSVUpdate(contours, Close_Contour_Index);
}
}
Scalar Push_Button(Rect2i roi_point) {
Mat hsv_frame;
hsv_frame = frame(roi_point).clone();
cvtColor(hsv_frame, hsv_frame, COLOR_BGR2HSV);
imshow("hsv_frame", hsv_frame);
return mean(hsv_frame);
}
int main() {
VideoCapture cap = VideoCapture(0);
if (!cap.isOpened()) {
cout << "Could't load camera" << endl;
return -1;
}
double width = cap.get(CAP_PROP_FRAME_WIDTH);
double height = cap.get(CAP_PROP_FRAME_HEIGHT);
width = 640;
height = 480;
cap.set(CAP_PROP_FRAME_WIDTH, width);
cap.set(CAP_PROP_FRAME_HEIGHT, height);
namedWindow("frame");
int key;
int frameCount = 0;
Scalar dis_HSV = Scalar(20, 20, 60);
Scalar lowerHSV, upperHSV;
Rect2i roi_frame = Rect(Point(width / 10 * 4, height / 10 * 5), Point(width / 10 * 6, height / 10 * 7));
while (1) {
cap >> frame;
flip(frame, frame, 1);
if (frame.empty()) {
cout << "Could't load frame" << endl;
return -1;
}
//Raspberry Camera Mode//
//Mat gaussian_blur;
//GaussianBlur(frame, gaussian_blur, Size(9, 9), 5);
//Mat sharpened = frame - gaussian_blur;
//Mat result = frame + sharpened;
key = waitKey(10);
if (key == 27) break;
else if (key == 32) {
meanHSV = Push_Button(roi_frame);
cout << "meanHSV : " << meanHSV << endl;
lowerHSV = meanHSV - dis_HSV;
upperHSV = meanHSV + dis_HSV;
}
if (meanHSV[0] != 0 || meanHSV[1] != 0 || meanHSV[2] != 0) {
HSV_Process(lowerHSV, upperHSV, Size(width, height));
}
rectangle(frame, roi_frame, Scalar(0, 0, 255), 2, 8);
imshow("frame", frame);
}
cap.release();
destroyAllWindows();
return 0;
}
'CELLON Kart(Tracking) > Source Code' 카테고리의 다른 글
CELLON Kart Source Code 1.3.4v(YCrCb) (2023.08.28) (0) | 2023.08.22 |
---|---|
CELLON Kart Source Code 1.3.3v (2023.08.22) (0) | 2023.08.22 |
CELLON Kart Source Code 1.3.1V (2023.08.02) (0) | 2023.08.02 |
CELLON Kart Source Code 1.3V (2023.07.27) (0) | 2023.07.27 |
CELLON Kart HSV detect Source Code (0) | 2023.07.12 |