Python中cv2.CC_STAT_AREA的用法
时间: 2024-09-11 07:03:04 浏览: 58
在Python的OpenCV库(cv2)中,`CC_STAT_AREA`是一个常量,它代表了轮廓属性(contour properties)中的“面积”计算标志。当你使用`findContours()`函数检测到图像中的轮廓,并对轮廓应用统计信息时,可以使用`cv2.contourArea()`函数,这个函数会返回轮廓的面积。`CC_STAT_AREA`通常作为参数传递给`cv2.RETR_EXTERNAL`或`cv2.RETR_CCOMP`等轮廓检索模式之一,以便获取所有外部轮廓或填充轮廓的面积。
例如,以下代码展示了如何使用:
```python
import cv2
import numpy as np
# 读取图像并转换为灰度
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 找到轮廓
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 遍历轮廓并计算每个轮廓的面积
for contour in contours:
area = cv2.contourArea(contour)
print(f"轮廓 {contour} 的面积: {area}")
```
在这个例子中,`CC_STAT_AREA`并没有直接用在函数调用中,但它被包含在`cv2.RETR_EXTERNAL`的参数中,表示我们想要轮廓的统计信息里包含面积。
相关问题
import numpy as np import cv2 as cv # 加载图片 img = cv.imread('4.jpg') # 灰度化 img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 二值化 ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY) # 寻找连通域 num_labels, labels, stats, centroids = cv.connectedComponentsWithStats(thresh, connectivity=8) # 计算平均面积 areas = list() for i in range(num_labels): areas.append(stats[i][-1]) print("轮廓%d的面积:%d" % (i, stats[i][-1])) area_avg = np.average(areas[1:-1]) print("轮廓平均面积:", area_avg) # 筛选超过平均面积的连通域 image_filtered = np.zeros_like(img) for (i, label) in enumerate(np.unique(labels)): # 如果是背景,忽略 if label == 0: continue if stats[i][-1] < area_avg : image_filtered[labels == i] = 255 #cv.imshow("image_filtered", image_filtered) #cv.imshow("img", img) cv.imwrite('4.jpg',image_filtered ) cv.waitKey() cv.destroyAllWindows(),将上述代码转化为c++形式
以下是将上述Python代码转化为C++形式的示例:
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
// 加载图片
Mat img = imread("4.jpg");
// 灰度化
Mat img_gray;
cvtColor(img, img_gray, COLOR_BGR2GRAY);
// 二值化
Mat thresh;
threshold(img_gray, thresh, 127, 255, THRESH_BINARY);
// 寻找连通域
Mat labels, stats, centroids;
int num_labels = connectedComponentsWithStats(thresh, labels, stats, centroids, 8);
// 计算平均面积
vector<int> areas;
for (int i = 0; i < num_labels; i++) {
areas.push_back(stats.at<int>(i, CC_STAT_AREA));
cout << "轮廓" << i << "的面积:" << stats.at<int>(i, CC_STAT_AREA) << endl;
}
double area_avg = mean(Mat(areas))[0];
cout << "轮廓平均面积:" << area_avg << endl;
// 筛选超过平均面积的连通域
Mat image_filtered = Mat::zeros(img.size(), CV_8UC1);
for (int i = 1; i < num_labels; i++) {
if (stats.at<int>(i, CC_STAT_AREA) < area_avg) {
labels.setTo(0, labels == i);
} else {
image_filtered.setTo(255, labels == i);
}
}
// 显示结果
imshow("image_filtered", image_filtered);
imshow("img", img);
waitKey();
destroyAllWindows();
// 保存结果
imwrite("4.jpg", image_filtered);
return 0;
}
```
需要注意的是,C++中没有Python中的`list`类型,需要使用`vector`替代。同时,C++中没有Python中的`np.average()`方法,需要使用OpenCV的`mean()`方法计算平均值。此外,C++中的Mat类需要使用`.at()`方法访问元素,而不是Python中的下标索引。
将以下的python程序转化为c++版本,并在vs2022上实现。import cv2 import numpy as np from skimage.transform import radon import os thre1=10 thre2=-10 r=60 maxVal = 0 index = 0 sequence_path = "./images/" for file in os.listdir(sequence_path): filename=os.path.join(sequence_path, file) image=cv2.imread(filename, 0) image=cv2.blur(image,(3,3)) img=np.zeros((len(image), len(image[0])),np.uint8) maxVal = 0 index = 0 retval, labels, stats, centroids = cv2.connectedComponentsWithStats(img, connectivity=8) for i in range(1, len(stats)): if stats[i][4] > maxVal: maxVal = stats[i][4] index = i #x,y,h,w s for i in range(len(labels)): for j in range(len(labels[0])): if labels[i][j]==index: labels[i][j]=255 else: labels[i][j] = 0 cv2.imwrite('./4-max_region.jpg',labels) img2=cv2.imread('./4-max_region.jpg',0) img3=cv2.Canny(img2,15,200) # theta = np.linspace(0, 180, endpoint=False) img4 = radon(img3) max_angel=0 for i in range(len(img4)): for j in range(len(img4[0])): if img4[i][j]>max_angel: max_angel=img4[i][j] angel=j print("{}方向为:{} °".format(filename,angel))
在VS2022上实现这段Python代码的C++版本,你可以使用以下代码作为参考:
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <opencv2/imgcodecs.hpp>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
using namespace cv;
int main() {
int thre1 = 10;
int thre2 = -10;
int r = 60;
int maxVal = 0;
int index = 0;
string sequence_path = "./images/";
for (const auto &entry : filesystem::directory_iterator(sequence_path)) {
string filename = entry.path().string();
Mat image = imread(filename, IMREAD_GRAYSCALE);
blur(image, image, Size(3,3));
Mat img(image.rows, image.cols, CV_8U, Scalar(0));
maxVal = 0;
index = 0;
Mat labels, stats, centroids;
int retval = connectedComponentsWithStats(img, labels, stats, centroids, 8);
for (int i = 1; i < stats.rows; i++) {
if (stats.at<int>(i, CC_STAT_AREA) > maxVal) {
maxVal = stats.at<int>(i, CC_STAT_AREA);
index = i;
}
}
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
if (labels.at<int>(i, j) == index)
labels.at<int>(i, j) = 255;
else
labels.at<int>(i, j) = 0;
}
}
imwrite("./4-max_region.jpg", labels);
Mat img2 = imread("./4-max_region.jpg", IMREAD_GRAYSCALE);
Mat img3;
Canny(img2, img3, 15, 200);
Mat img4;
radon(img3, img4);
int max_angel = 0;
int angel = 0;
for (int i = 0; i < img4.rows; i++) {
for (int j = 0; j < img4.cols; j++) {
if (img4.at<float>(i, j) > max_angel) {
max_angel = img4.at<float>(i, j);
angel = j;
}
}
}
cout << filename << " 方向为:" << angel << " °" << endl;
}
return 0;
}
```
请注意,你需要在项目中添加OpenCV库的链接。此外,代码中使用了C++17的filesystem库进行文件遍历,因此你需要在编译时启用C++17标准。
阅读全文