图像处理七:图像矩

版权声明:本文为博主原创文章,未经博主允许不得转载。 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)

猜你喜欢

转载自blog.csdn.net/yql_617540298/article/details/84935283