影象處理七:影象矩
阿新 • • 發佈:2018-12-10
一、影象
影象:對應矩陣,每個位置的元素就是該處的畫素;
影象矩:一個從數字圖形中計算出來的矩集,通常描述了該影象全域性特徵,並提出了大量的關於該影象不同型別的幾何特徵資訊;(如大小、位置、方向和形狀等);
一階矩:與形狀有關;
二階矩:顯示了曲線圍繞直線平均值的擴充套件程度;
三階矩:關於平均值的對稱性測量;
通過二階矩計算影象中心: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)