寻找连通域的质心

MATLAB
1、灰度化
2、二值化
3、取反
4、连通域标记
连通域标记
5、对每个连通域,计算x坐标和,y坐标和,分别除以面积则为质心坐标

clear;clc;close all;
I=imread('1.png');%读取原图像
figure(1);imshow(I);%显示原图像

I_gray=rgb2gray(I);%原图像变为灰度图像
level=graythresh(I_gray);%计算图像I_gray的全局阈值,level为标准化灰度值,其范围为[0 1]
[height,width]=size(I_gray);%计算灰度图像的长宽
I_bw=im2bw(I_gray,level);%im2bw使用阈值level将灰度图像转换为二值图像.
figure(2);imshow(I_bw);%显示二值图像(背景为白色)

for i=1:height %%循环中进行反色
    for j=1:width   
        if I_bw(i,j)==1      
            I_bw(i,j)=0;  
        else I_bw(i,j)=1; 
        end
    end
end
figure(3);imshow(I_bw);%显示取反后的二值图像(背景为黑色)

[L,num]=bwlabel(I_bw,8);%bwlabel标注二值图像I_bw中的目标物体,返回标识矩阵L和I_bw中目标物体的数量num,8表示连通数.
plot_x=zeros(1,num);%%zeros(m,n)产生m×n的全0矩阵.用于记录质心位置的横坐标
plot_y=zeros(1,num);%zeros(m,n)产生m×n的全0矩阵.用于记录质心位置的纵坐标

for k=1:num  %%num个区域依次统计质心位置    
    sum_x=0;    sum_y=0;    area=0; %初始化
    for i=1:height   
        for j=1:width 
            if L(i,j)==k     
                sum_x=sum_x+i;  %计算第K区域的横坐标总和
                sum_y=sum_y+j;  %计算第K区域的纵坐标总和 
                area=area+1;    %计算第K区域的由多少个坐标点表示
            end
        end
    end
    plot_x(k)=fix(sum_x/area);  %计算第K区域的质心横坐标
    plot_y(k)=fix(sum_y/area);%计算第K区域的质心纵坐标
end

figure(4);imshow(I_bw);%显示取反后的二值图像(背景为黑色),并在图上标注质心点位置
for i=1:num
    hold  on
    plot(plot_y(i) ,plot_x(i), '*')
end

在这里插入图片描述
C++
1、灰度化
2、高斯滤波
3、canny算子边缘检测
4、寻找轮廓
5、寻找轮廓的矩,计算质心
5、画出轮廓,画出外接矩形以及质心


#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv/cv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;
Mat src;
Mat src_gray;
int thresh = 30;
int max_thresh = 255;

int main()
{
	src = imread("E:\\Exercise\\VS\\project\\运动检测\\混合高斯模型\\1.png", CV_LOAD_IMAGE_COLOR); 	//注意路径得换成自己的
	cvtColor(src, src_gray, CV_BGR2GRAY);//灰度化 	
	GaussianBlur(src, src, Size(3, 3), 0.1, 0, BORDER_DEFAULT);
	blur(src_gray, src_gray, Size(3, 3)); //滤波 	
	namedWindow("image", CV_WINDOW_AUTOSIZE);
	imshow("image", src);
	moveWindow("image", 20, 20);
	//定义Canny边缘检测图像 	
	Mat canny_output;
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;
	//利用canny算法检测边缘 	
	Canny(src_gray, canny_output, thresh, thresh * 3, 3);
	namedWindow("canny", CV_WINDOW_AUTOSIZE);
	imshow("canny", canny_output);
	moveWindow("canny", 550, 20);
	//查找轮廓 	
	findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
	//计算轮廓矩 	
	vector<Moments> mu(contours.size());
	for (int i = 0; i < contours.size(); i++)
	{
		mu[i] = moments(contours[i], false);
	}
	//计算轮廓的质心 	
	vector<Point2f> mc(contours.size());
	for (int i = 0; i < contours.size(); i++)
	{
		mc[i] = Point2d(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
	}
	//画轮廓及其质心并显示 	
	Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
	for (int i = 0; i < contours.size(); i++)
	{
		Scalar color = Scalar(255, 0, 0);
		drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
		circle(drawing, mc[i], 5, Scalar(0, 0, 255), -1, 8, 0);
		rectangle(drawing, boundingRect(contours.at(i)), cvScalar(0, 255, 0));
		char tam[100];
		//printf(tam, "(%0.0f,%0.0f)", mc[i].x, mc[i].y);
		putText(drawing, tam, Point(mc[i].x, mc[i].y), FONT_HERSHEY_SIMPLEX, 0.4, cvScalar(255, 0, 255), 1);
	}
	namedWindow("Contours", CV_WINDOW_AUTOSIZE);
	imshow("Contours", drawing);
	moveWindow("Contours", 1100, 20);
	waitKey(0);
	src.release();
	src_gray.release();
	return 0;
}
#coding=utf-8
import cv2
import numpy as np
 
 
img = cv2.imread('./image/multiple.png')
 
# convert the image to grayscale
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# convert the grayscale image to binary image
ret,thresh = cv2.threshold(gray_image,127,255,0)
 
# find contour in the binary image
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# find contour in the binary image(opencv4)
#binary, contours, opt  = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
	# calculate moments for each contour
	M = cv2.moments(c)
	cX = int(M["m10"] / M["m00"])
	cY = int(M["m01"] / M["m00"])
	
	
    # calculate x,y coordinate of center
	cv2.circle(img, (cX, cY), 5, (255, 255, 255), -1)
	cv2.putText(img, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
 
 
# 3.4.1 im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# 3.2.0 im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 	
 
# display the image
cv2.imshow("Image", img)
cv2.waitKey(0)
  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一种使用Python实现的区域生长法来计连通域质心点的代码: ```python import numpy as np def region_growing(image, threshold): """ 使用区域生长法来计图像中的连通域 :param image: 原始图像,二维numpy数组 :param threshold: 生长阈值 :return: 连通域列表,每个连通域包含其像素坐标和质心坐标 """ # 初始化 rows, cols = image.shape visited = np.zeros((rows, cols), dtype=bool) regions = [] # 区域生长法 for i in range(rows): for j in range(cols): if not visited[i, j]: region = [] queue = [(i, j)] visited[i, j] = True while queue: x, y = queue.pop(0) region.append((x, y)) if x > 0 and not visited[x-1, y] and abs(image[x, y] - image[x-1, y]) < threshold: queue.append((x-1, y)) visited[x-1, y] = True if x < rows-1 and not visited[x+1, y] and abs(image[x, y] - image[x+1, y]) < threshold: queue.append((x+1, y)) visited[x+1, y] = True if y > 0 and not visited[x, y-1] and abs(image[x, y] - image[x, y-1]) < threshold: queue.append((x, y-1)) visited[x, y-1] = True if y < cols-1 and not visited[x, y+1] and abs(image[x, y] - image[x, y+1]) < threshold: queue.append((x, y+1)) visited[x, y+1] = True if len(region) > 0: region = np.array(region) centroid = np.mean(region, axis=0) regions.append({'pixels': region, 'centroid': centroid}) return regions ``` 在此代码中,我们使用一个二维numpy数组来表示原始图像,并使用阈值作为生长条件。法遍历图像的每个像素,并将它与其相邻的像素进行比较。如果它们之间的差异小于阈值,则将其添加到同一连通域中,并将其标记为已访问。最终,我们计每个连通域质心坐标作为其特征,并将其保存在一个列表中返回。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值