版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yql_617540298/article/details/84935283
一、图像
图像:对应矩阵,每个位置的元素就是该处的像素;
图像矩:一个从数字图形中计算出来的矩集,通常描述了该图像全局特征,并提出了大量的关于该图像不同类型的几何特征信息;(如大小、位置、方向和形状等);
一阶矩:与形状有关;
二阶矩:显示了曲线围绕直线平均值的扩展程度;
三阶矩:关于平均值的对称性测量;
通过二阶矩计算图像中心:python
import imutils
import cv2
import os
#ap = argparse.ArgumentParser()
#--image 参数: 磁盘中待处理图像的路径
#ap.add_argument("-i","--image",required=True,help="path to the input image")
#args = vars(ap.parse_args())
#image = cv2.imread(args["image"])
filepath = 'C:/Users/Administrator/Desktop/result/'
resultpath = 'C:/Users/Administrator/Desktop/result_zx/'
count = os.listdir(filepath)
for i in range(0,len(count)):
print("i=",i)
image = cv2.imread(filepath+str(i)+'.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#5×5 内核的高斯平滑
blurred = cv2.GaussianBlur(gray,(5,5),0)
#阈值化
thresh = cv2.threshold(blurred,60,255,cv2.THRESH_BINARY)[1]
#使用轮廓检测去定位这些白色区域
#返回图像上每一个白块对应的边界点集合(即轮廓)
cnts = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
#处理每一条轮廓
for c in cnts:
#计算轮廓区域图像的矩
M = cv2.moments(c)
print("M:",M)
if M["m00"]==0:
print("skip!")
else:
#计算轮廓的中心
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
#在形状的中心 (cX, cY) 处绘制一个白色的小圆
cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)
cv2.putText(image, "", (cX - 20, cY - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
cv2.imwrite(resultpath+str(i)+'.png',image)
#cv2.imshow("Image", image)
cv2.waitKey(0)
通过二阶矩计算图像重心:MATLAB
for i=0:29
%I = imread('picture\0.png');
bgFile = ['picture\',int2str(i),'.png'];% 读入图片的完整路径
I = imread(bgFile);
I = rgb2gray(I);
imshow(I);
I = double(I);
[rows,cols] = size(I);
x = ones(rows,1)*[1:cols];
y = [1:rows]'*ones(1,cols);
area = sum(sum(I));
meanx = sum(sum(I.*x))/area;
meany = sum(sum(I.*y))/area;
hold on;
plot(meanx,meany,'r+'); %十字标出重心位置
F=getframe(gcf); % 获取整个窗口内容的图像
%imwrite(F.cdata,'result\1.png')
img = ['result\',num2str(i),'.png']
imwrite(F.cdata,img);
hold off;
end;
二、中心距求主轴方向
引用原文链接:https://blog.csdn.net/hong__fang/article/details/49851569
1. 中心距
2. 中心距求主轴方向
主轴方向与x轴正向的最小夹角,如果角度位于y正方向,则,位于y负方向, 。
求中心距求主轴另外公式:
求中心距时,如果是二值图像,可以只根据图像边界坐标求主方向,与利用图像所有坐标求主轴方向相比,只利用边界坐标会存在一定偏差,约
MATLAB实现:主轴方向
function test
I = imread('picture\0.png');
[cm ju] = qijieju(uint8(I));
m00 = cm(1);
mu11 = cm(2);
mu02 = cm(3);
mu20 = cm(4);
a = mu20 / m00;
b = mu11 / m00;
c = mu02 / m00;
square = sqrt( 4 * b * b + (a - c) * (a - c) );
%求主轴方法1
theta1 = atan2( 2 * b, a - c + square )*180/pi
%save('output\output.txt','theta1','-ascii')
%B = imrotate(I,theta1,'bicubic')
%imwrite(B,'output\1.png')
%求主轴方法2
theta2 = atan2(2*mu11,(mu20-mu02))/2*180/pi
I2 = imrotate(I,-theta2*10,'nearest')
imwrite(I2,'output\0.png')
end
%求不变矩及中心矩
function [cm ju] = qijieju(I0)
A=double(I0);
[nc,nr]=size(A);
[x,y]=meshgrid(1:nr,1:nc);
x=x(:);
y=y(:);
A=A(:);
m00=sum(A);
if m00==0
m00=eps;
end
m10=sum(x.*A);
m01=sum(y.*A);
xmean=m10/m00; %重心
ymean=m01/m00;
cm00=m00; %归一化中心矩
cm02=(sum((y-ymean).^2.*A))/(m00^2);
cm03=(sum((y-ymean).^3.*A))/(m00^2.5);
cm11=(sum((x-ymean).*(y-ymean).*A))/(m00^2);
cm12=(sum((x-ymean).*(y-ymean).^2.*A))/(m00^2.5);
cm20=(sum((x-xmean).^2.*A))/(m00^2);
cm21=(sum((x-xmean).^2.*(y-ymean).*A))/(m00^2.5);
cm30=(sum((x-xmean).^3.*A))/(m00^2.5);
ju(1)=cm20+cm02; %
ju(2)=(cm20-cm02)^2+4*cm11^2; %
ju(3)=(cm30-3*cm12)^2+(3*cm21-cm03)^2; %
ju(4)=(cm30+cm12)^2+(cm21+cm03)^2; %
ju(5)=(cm30-3*cm12)*(cm30+cm12)*((cm30+cm12)^2-3*(cm21+cm03)^2)+(3*cm21-cm03)*(cm21+cm03)*(3*(cm30+cm12)^2-(cm21+cm03)^2); %
ju(6)=(cm20-cm02)*((cm30+cm12)^2-(cm21+cm03)^2)+4*cm11*(cm30+cm12)*(cm21+cm03); %
ju(7)=(3*cm21-cm03)*(cm30+cm12)*((cm30+cm12)^2-3*(cm21+cm03)^2)+(cm30-3*cm12)*(cm21+cm03)*(3*(cm30+cm12)^2-(cm21+cm03)^2);
qijieju= ju;%abs(log(ju))
cm = [cm00 cm11 cm02 cm20];
end
三、通过两点计算夹角
python实现
def azimuthAngle( x1, y1, x2, y2):
angle = 0.0
dx = x2 - x1
dy = y2 - y1
angle = math.atan(dy/dx)
return (angle * 180 / math.pi)
angle = azimuthAngle(x1,y1,x2,y2)
print("angle=",angle)