#pragma once #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include<iostream> #include<vector> using namespace std; using namespace cv; // Lớp chứa các blob class Blob { public: int xmax, xmin, ymax, ymin, xcenter, ycenter; vector<Point> region; int width, height; int size; bool isInBlob(Point a) { if (a.x >= xmin - 2 && a.x <= xmax + 2 && a.y >= ymin - 2 && a.y <= ymax + 2) return true; return false; } void Add(Point a) { region.push_back(a); xmax = max(a.x, xmax); xmin = min(a.x, xmin); ymin = min(a.y, ymin); ymax = max(a.y, ymax); xcenter = (xmax + xmin) / 2; ycenter = (ymax + ymin) / 2; size = (xmax - xmin) * (ymax - ymin); width = xmax - xmin; height = ymax - ymin; } Blob() { xmax = ymax = xcenter = ycenter = size = 0; width = height = 0; xmin = ymin = INT_MAX; } ~Blob() {} };
时间: 2023-06-17 17:04:26 浏览: 204
这是一个使用OpenCV库实现的Blob类,用于表示图像中的连通区域。Blob类具有以下属性和方法:
属性:
- xmax, xmin, ymax, ymin:表示连通区域的最大和最小的x和y坐标。
- xcenter, ycenter:表示连通区域的中心点坐标。
- region:表示连通区域内所有像素的坐标。
- width, height:表示连通区域的宽度和高度。
- size:表示连通区域的面积。
方法:
- isInBlob(Point a):判断一个点是否在该Blob中。
- Add(Point a):将一个点添加到该Blob中。
可以通过使用Blob类来实现图像分割、目标检测等应用。
相关问题
C++ Dll项目 cpp新建OpenCV 函数 编写相关cpp 和头文件
在 Visual Studio 中新建一个 DLL 项目,然后添加 OpenCV 库文件和头文件。
1. 在项目属性中,选择 Configuration Properties -> General,将 Configuration Type 设置为 Dynamic Library (.dll)。
2. 在项目属性中,选择 Configuration Properties -> C/C++ -> General,将 Additional Include Directories 添加 OpenCV 的 include 文件夹路径。
3. 在项目属性中,选择 Configuration Properties -> Linker -> General,将 Additional Library Directories 添加 OpenCV 的 lib 文件夹路径。
4. 在项目属性中,选择 Configuration Properties -> Linker -> Input,将 Additional Dependencies 添加以下库文件:
```
opencv_core410d.lib
opencv_highgui410d.lib
```
5. 在项目中添加一个新的 C++ 源文件,用于编写 OpenCV 相关的函数。
6. 在该源文件中添加头文件:
```cpp
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
```
7. 在该源文件中编写 OpenCV 相关的函数。例如:
```cpp
void showImage(const char* filename)
{
cv::Mat image = cv::imread(filename, cv::IMREAD_COLOR);
cv::imshow("Image", image);
cv::waitKey(0);
}
```
8. 在该源文件中添加导出函数声明:
```cpp
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void showImage(const char* filename);
#ifdef __cplusplus
}
#endif
```
9. 在项目中添加一个新的头文件,用于声明导出函数。
```cpp
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void showImage(const char* filename);
#ifdef __cplusplus
}
#endif
```
10. 在该头文件中添加所有需要导出的函数声明。
11. 编译项目并生成 DLL 文件。
12. 可以在其他项目中引用该 DLL 文件,并使用其中的函数。
用C++,openmp,opencv实现连通区域标记的二遍扫描算法,要先将输入的图像二值化,并且用动态二维数组来存储每个像素所属的连通区域标记
以下是用C,OpenMP和OpenCV实现的连通区域标记的二遍扫描算法的示例代码。在此示例中,输入图像被假设为名为“input.png”的PNG文件,并且输出图像被保存为名为“output.png”的PNG文件。
```
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main(int argc, char** argv)
{
// Read input image
Mat input = imread("input.png", CV_LOAD_IMAGE_GRAYSCALE);
int height = input.rows;
int width = input.cols;
// Binarize input image
Mat binary;
threshold(input, binary, 128, 255, THRESH_BINARY);
// Allocate dynamic 2D array to store labels
int** labels = new int*[height];
for (int i = 0; i < height; i++)
labels[i] = new int[width];
// Initialize labels to -1
#pragma omp parallel for
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
labels[i][j] = -1;
// First pass
int next_label = 0;
#pragma omp parallel for
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (binary.at<uchar>(i, j) == 255) {
int left = (j > 0) ? labels[i][j-1] : -1;
int up = (i > 0) ? labels[i-1][j] : -1;
if (left == -1 && up == -1) { // Create new label
labels[i][j] = next_label;
next_label++;
} else if (left == -1) { // Use up label
labels[i][j] = up;
} else if (up == -1) { // Use left label
labels[i][j] = left;
} else { // Merge labels
int min_label = (left < up) ? left : up;
int max_label = (left > up) ? left : up;
labels[i][j] = min_label;
#pragma omp parallel for
for (int ii = 0; ii < height; ii++) {
for (int jj = 0; jj < width; jj++) {
if (labels[ii][jj] == max_label)
labels[ii][jj] = min_label;
}
}
}
}
}
}
// Second pass
int* counts = new int[next_label];
for (int i = 0; i < next_label; i++)
counts[i] = 0;
#pragma omp parallel for
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (labels[i][j] >= 0) {
int label = labels[i][j];
#pragma omp atomic
counts[label]++;
}
}
}
#pragma omp parallel for
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (labels[i][j] >= 0) {
int label = labels[i][j];
int count = counts[label];
int color = (count > 200) ? 255 : 0; // Threshold count
binary.at<uchar>(i, j) = color;
}
}
}
// Save output image
imwrite("output.png", binary);
// Deallocate dynamic 2D array
for (int i = 0; i < height; i++)
delete[] labels[i];
delete[] labels;
delete[] counts;
return 0;
}
```
在此示例中,算法的第一遍扫描通过使用OpenMP并行化来加速计算。第二遍扫描也使用OpenMP并行化,但是在计算每个连通区域的像素计数时使用了OpenMP原子操作,以确保线程安全。算法还使用OpenCV中的threshold函数来执行二值化,并使用Mat对象来处理图像。
阅读全文