Initial.
This commit is contained in:
commit
879cbc4a32
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
*.o
|
||||
obj/
|
||||
*.out
|
||||
.cache/
|
||||
dataset/
|
||||
testimgs/
|
||||
compile_commands.json
|
29
Makefile
Normal file
29
Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
NAME = imgboxer
|
||||
|
||||
CXX = g++
|
||||
CXXFLAGS = -Wall -std=c++11 `pkg-config --cflags opencv4`
|
||||
LDFLAGS = `pkg-config --libs opencv4`
|
||||
|
||||
SRC_DIR = src
|
||||
OBJ_DIR = obj
|
||||
TARGET = $(NAME).out
|
||||
|
||||
SRC_FILES = $(wildcard $(SRC_DIR)/*.cpp)
|
||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRC_FILES))
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ_FILES)
|
||||
@ echo -e "\x1b[32;1mLinking \x1b[0m\x1b[32m$(TARGET)\x1b[32;1m...\x1b[0m\x1b[37m $(CXX) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)\x1b[0m"
|
||||
@ $(CXX) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/include/%.hpp
|
||||
@ mkdir -p $(OBJ_DIR)
|
||||
@ echo -e "\x1b[32;1mCompiling \x1b[0m\x1b[32m$<\x1b[32;1m... \x1b[0m\x1b[37m$(CXX) $(CXXFLAGS) -c $< -o $@\x1b[0m"
|
||||
@ $(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@ echo -e "\x1b[32;1mCleaning up...\x1b[0m"
|
||||
@ rm -rf $(OBJ_DIR) $(TARGET)
|
||||
|
||||
.PHONY: all clean
|
23
src/bound.cpp
Normal file
23
src/bound.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "include/bound.hpp"
|
||||
|
||||
std::vector<std::vector<cv::Point>> bound_contours(cv::Mat img) {
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
cv::findContours(img, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
|
||||
|
||||
return contours;
|
||||
}
|
||||
|
||||
std::vector<cv::Rect>
|
||||
bound_boxes(std::vector<std::vector<cv::Point>> contours) {
|
||||
std::vector<cv::Rect> boxes;;
|
||||
|
||||
for (size_t i = 0; i < contours.size(); i++) {
|
||||
cv::Rect box = cv::boundingRect(contours[i]);
|
||||
|
||||
if (box.width < BOUND_MIN_W && box.height < BOUND_MIN_H) continue;
|
||||
|
||||
boxes.push_back(box);
|
||||
}
|
||||
|
||||
return boxes;
|
||||
}
|
5
src/img.cpp
Normal file
5
src/img.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "include/img.hpp"
|
||||
|
||||
cv::Mat img_get(char* fpath) {
|
||||
return cv::imread(fpath, cv::IMREAD_GRAYSCALE);
|
||||
}
|
17
src/include/bound.hpp
Normal file
17
src/include/bound.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef BOUND_H
|
||||
#define BOUND_H
|
||||
|
||||
// Create bounding boxes and contours for images.
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#define BOUND_MIN_W 90
|
||||
#define BOUND_MIN_H BOUND_MIN_W
|
||||
|
||||
// Return list of coutours.
|
||||
std::vector<std::vector<cv::Point>> bound_contours(cv::Mat img);
|
||||
|
||||
// Return list of boxes.
|
||||
std::vector<cv::Rect> bound_boxes(std::vector<std::vector<cv::Point>> contours);
|
||||
|
||||
#endif
|
10
src/include/img.hpp
Normal file
10
src/include/img.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef IMG_H
|
||||
#define IMG_H
|
||||
|
||||
// Read in images.
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
cv::Mat img_get(char* fpath);
|
||||
|
||||
#endif
|
15
src/include/main.hpp
Normal file
15
src/include/main.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include "img.hpp"
|
||||
#include "preprocess.hpp"
|
||||
#include "bound.hpp"
|
||||
#include "yolo.hpp"
|
||||
|
||||
int main(int argc, char** argv);
|
||||
|
||||
#endif
|
10
src/include/preprocess.hpp
Normal file
10
src/include/preprocess.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef PREPROCESS_H
|
||||
#define PREPROCESS_H
|
||||
|
||||
// Pre-process images (apply filters, grayscale, &c.)
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
cv::Mat preprocess_threshold(cv::Mat img);
|
||||
|
||||
#endif
|
28
src/include/yolo.hpp
Normal file
28
src/include/yolo.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef YOLO_H
|
||||
#define YOLO_H
|
||||
|
||||
// Create the YOLOv8 image labels.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
// Name to assign to all labels.
|
||||
#define LABEL_NAME "tooth"
|
||||
|
||||
typedef struct Label {
|
||||
int confidence;
|
||||
int xmin;
|
||||
int ymin;
|
||||
int xmax;
|
||||
int ymax;
|
||||
} label_t;
|
||||
|
||||
label_t* yolo_mklabel(cv::Rect box);
|
||||
|
||||
// Write labels to file from cv::Rect.
|
||||
void yolo_write_labels(char* fname, std::vector<cv::Rect> boxes);
|
||||
|
||||
|
||||
#endif
|
41
src/main.cpp
Normal file
41
src/main.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "include/main.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Check for invalid invocation.
|
||||
if (argc != 2) {
|
||||
printf("%s IMAGE", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read in image.
|
||||
cv::Mat img = img_get(argv[1]);
|
||||
|
||||
// Check the image actually exists.
|
||||
if (img.empty()) {
|
||||
std::cout << "File not found: " << argv[1] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Threshold the image (in case it's not already binary).
|
||||
cv::Mat binimg = preprocess_threshold(img);
|
||||
|
||||
vector<vector<Point>> contours = bound_contours(binimg);
|
||||
vector<Rect> boxes = bound_boxes(contours);
|
||||
|
||||
for (size_t i = 0; i < contours.size(); i++) {
|
||||
rectangle(img, boxes[i], Scalar(255, 255, 255), 1);
|
||||
drawContours(img, contours, (int)i, Scalar(255, 255, 255), 1, LINE_8);
|
||||
}
|
||||
|
||||
yolo_write_labels("asdf", boxes);
|
||||
|
||||
// Show image with bounding boxes.
|
||||
imshow("Bounding Boxes", img);
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
7
src/preprocess.cpp
Normal file
7
src/preprocess.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "include/preprocess.hpp"
|
||||
|
||||
cv::Mat preprocess_threshold(cv::Mat img) {
|
||||
cv::Mat binimg;
|
||||
cv::threshold(img, binimg, 128, 255, cv::THRESH_BINARY);
|
||||
return binimg;
|
||||
}
|
21
src/yolo.cpp
Normal file
21
src/yolo.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "include/yolo.hpp"
|
||||
|
||||
label_t* yolo_mklabel(cv::Rect box) {
|
||||
// why is c++ like this
|
||||
label_t* label = (label_t*)malloc(sizeof(label_t));
|
||||
|
||||
label->confidence = 1;
|
||||
label->xmin = box.x;
|
||||
label->ymin = box.y;
|
||||
label->xmax = box.x + box.width;
|
||||
label->ymax = box.y + box.height;
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
void yolo_write_labels(char* fname, std::vector<cv::Rect> boxes) {
|
||||
for (size_t i = 0; i < boxes.size(); i++) {
|
||||
auto box = boxes[i];
|
||||
printf("%s 1 %d %d %d %d\n", LABEL_NAME, box.x, box.y, box.x + box.width, box.y + box.height);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user