python计算重心坐标 python求质心坐标_图像识别


实现openCV-python批量转换质心坐标输出txt源码案例,批量化操作。

import cv2
import os
import numpy as np
import functools
def sys_moments(img):
    moments = cv2.moments(img)#返回的是一个字典,三阶及以下的几何矩(mpq)、中心矩(mupq)和归一化的矩(nupq)
    humoments = cv2.HuMoments(moments)#根据几何矩(mpq)、中心矩(mupq)和归一化的矩(nupq)计算出hu不变矩
    humoment = -(np.log(np.abs(humoments)))/np.log(10)
    return humoment
def main():
    f1 = open("S:\\AdobeppPS\\ceshi02.txt",'w+')
    input_dir = "S:\\AdobeppPS\\SKOO\\"
    aa = os.listdir( input_dir) 
    abc=0
    set_list = []
    list00=[]
    tholdzz=127
    zs=len(aa)*7
    cxx=[]
    cyy=[]
    for ia in aa:
        grayy=cv2.imread(input_dir+ia,0)
#         gray_image = cv2.cvtColor(grayy, cv2.COLOR_BGR2GRAY)
        ret,thresh = cv2.threshold(gray_image,tholdzz,255,0)
        ret,thresh = cv2.threshold(grayy,tholdzz,255,0)
        M = cv2.moments(thresh)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
        cxx.append(cX)
        cyy.append(cY)
        cv2.circle(grayy, (cX, cY), 5, (255, 255, 255), -1)
        cv2.putText(grayy, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
        print("质心坐标为:",cX,cY)     
        
        arr1=sys_moments(grayy)  
        for item in range(len(arr1)):
            s=arr1[item,0]
            set_list.append(s)
            list00.append(s)
    for cs0 in range(zs):
        if cs0%7==0:
            abc=abc+1
            f1.write("第 "+str(abc)+"张图片的质心坐标为:"+str(cxx[abc-1])+"\t"+str(cyy[abc-1]) +"\n")
    f1.close()    
if __name__ == '__main__':
    main()   
    print("well done")

全套整理质心源码如下:
包括单个,多个质心,以及批量化输出

#单个质心获取
import cv2
import numpy as np 
img01="S:\\AdobeppPS\\SKOO\\cc15.jpg"
img = cv2.imread(img01) 
# convert image to grayscale image
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
# convert the grayscale image to binary image
ret,thresh = cv2.threshold(gray_image,127,255,0) 
# calculate moments of binary image
M = cv2.moments(thresh) 
# calculate x,y coordinate of center
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"]) 
# put text and highlight the 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)
 
# display the image
cv2.imshow("Image", img)
cv2.waitKey(0)
print("质心坐标为:",cX,cY)

'''#多质心
import cv2
import numpy as np 
img01="S:\\AdobeppPS\\SKOO\\cc99.jpg"
img = cv2.imread(img01) 
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)
# show the image
cv2.imshow("Image", img)
cv2.waitKey(0)
print(cX,cY)

#批量化输出
import cv2
import os
import numpy as np
import functools
def sys_moments(img):
    moments = cv2.moments(img)#返回的是一个字典,三阶及以下的几何矩(mpq)、中心矩(mupq)和归一化的矩(nupq)
    humoments = cv2.HuMoments(moments)#根据几何矩(mpq)、中心矩(mupq)和归一化的矩(nupq)计算出hu不变矩
    humoment = -(np.log(np.abs(humoments)))/np.log(10)
    return humoment
def main():
    f1 = open("S:\\AdobeppPS\\ceshi02.txt",'w+')
    input_dir = "S:\\AdobeppPS\\SKOO\\"
    aa = os.listdir( input_dir) 
    abc=0
    set_list = []
    list00=[]
    tholdzz=127
    zs=len(aa)*7
    cxx=[]
    cyy=[]
    for ia in aa:
        grayy=cv2.imread(input_dir+ia,0)
#         gray_image = cv2.cvtColor(grayy, cv2.COLOR_BGR2GRAY)
        ret,thresh = cv2.threshold(gray_image,tholdzz,255,0)
        ret,thresh = cv2.threshold(grayy,tholdzz,255,0)
        M = cv2.moments(thresh)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
        cxx.append(cX)
        cyy.append(cY)
        cv2.circle(grayy, (cX, cY), 5, (255, 255, 255), -1)
        cv2.putText(grayy, "centroid", (cX - 25, cY - 25),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
#         print("质心坐标为:",cX,cY)     
        
        arr1=sys_moments(grayy)  
        for item in range(len(arr1)):
            s=arr1[item,0]
            set_list.append(s)
            list00.append(s)
    for cs0 in range(zs):
        if cs0%7==0:
            abc=abc+1
        
#         f1.write("第 "+str(abc)+"张图片:\t"+str(format(list00[cs0],".3f"))+"\n")
            f1.write("第 "+str(abc)+"张图片的质心坐标为:"+str(cxx[abc-1])+"\t"+str(cyy[abc-1]) +"\n")
    f1.close()    
if __name__ == '__main__':
    main()   
    print("well done")    
'''

附注插上:
OpenCV函数resize原型:
cv2.resize(InputArray src, OutputArray dst, Size, fx, fy, interpolation)
参数解释:
InputArray src 输入图片
OutputArray dst 输出图片
Size 输出图片尺寸
fx, fy 沿x轴,y轴的缩放系数
1.输出尺寸格式为(宽,高)
2.默认的插值方法为:双线性插值

interpolation 插入方式----官网介绍

interpolation 选项所用的插值方法:
INTER_NEAREST - 最近邻插值
INTER_LINEAR - 双线性插值(默认使用)
INTER_AREA - 使用像素区域关系重新采样。它可能是图像抽取的首选方法,因为它提供无摩尔纹的结果。但是当图像被放大时,它的INTER_NEAREST 方法是类似的 。
INTER_CUBIC - 4x4 像素邻域上的双三次插值
INTER_LANCZOS4 - 8x8 像素邻域上的 Lanczos 插值

在某些情况下,我们需要使用不同分辨率的(相同)图像。例如,当在图像中搜索某些东西(例如人脸)时,我们不确定对象将以多大的尺寸显示在图像中。在这种情况下,我们将需要创建一组具有不同分辨率的相同图像,并在所有图像中搜索对象。这些具有不同分辨率的图像集称为“图像金字塔”(因为当它们堆叠在底部时,最高分辨率的图像位于顶部,最低分辨率的图像位于顶部时,看起来像金字塔)。

有两种图像金字塔。1)高斯金字塔和2)拉普拉斯金字塔

1、高斯金字塔

高斯金字塔中的较高级别(低分辨率)是通过删除较低级别(较高分辨率)图像中的连续行和列而形成的。然后,较高级别的每个像素由基础级别的5个像素的贡献与高斯权重形成。通过这样做,M×N图像变成M/2×N/2图像。因此面积减少到原始面积的四分之一。它称为Octave。当我们在金字塔中越靠上时(即分辨率下降),这种模式就会继续。同样,在扩展时,每个级别的面积变为4倍。我们可以使用cv.pyrDown()和cv.pyrUp()函数找到高斯金字塔。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
from google.colab.patches import cv2_imshow
img=cv.imread(‘梅西.jpg’,1)
lower_reso1 = cv.pyrDown(img)
lower_reso2 = cv.pyrDown(lower_reso1)
cv2_imshow(img)
cv2_imshow(lower_reso1)
cv2_imshow(lower_reso2)

higher_reso1 = cv.pyrUp(lower_reso1)

拉普拉斯金字塔由高斯金字塔形成。没有专用功能。拉普拉斯金字塔图像仅像边缘图像。它的大多数元素为零。它们用于图像压缩。拉普拉斯金字塔的层由高斯金字塔的层与高斯金字塔的高层的扩展版本之间的差形成。拉普拉斯等级的三个等级如下所示(调整对比度以增强内容):要求:拉普拉斯金字塔时,图像大小必须是2的n次方*2的n次方,不然会报错。

金字塔的一种应用是图像融合。例如,在图像拼接中,您需要将两个图像堆叠在一起,但是由于图像之间的不连续性,可能看起来不太好。在这种情况下,使用金字塔混合图像可以无缝混合,而不会在图像中保留大量数据。

更多

图像金字塔就是用来进行图像缩放的,干的事情跟resize函数没两样,那我们还需要学它吗?我觉得有必要的额,因为在学习卷积神经网络一层层的图像比喻为金字塔,层级越高,则图像尺寸越小,分辨率越低。
两种类型的金字塔:
高斯金字塔:用于下采样,主要的图像金字塔;
拉普拉斯金字塔:用于重建图像,也就是预测残差(我的理解是,因为小图像放大,必须插入一些像素值,那这些像素值是什么才合适呢,那就得进行根据周围像素进行预测),对图像进行最大程度的还原。比如一幅小图像重建为一幅大图像,
图像金字塔有两个高频出现的名词:上采样和下采样。
上采样:就是图片放大(所谓上嘛,就是变大),使用PryUp函数
下采样:就是图片缩小(所谓下嘛,就是变小),使用PryDown函数
下采样将步骤:
对图像进行高斯内核卷积
将所有偶数行和列去除
下采样就是图像压缩,会丢失图像信息。
上采样步骤:
将图像在每个方向放大为原来的两倍,新增的行和列用0填充;
使用先前同样的内核(乘以4)与放大后的图像卷积,获得新增像素的近似值。
上、下采样都存在一个严重的问题,那就是图像变模糊了,因为缩放的过程中发生了信息丢失的问题。要解决这个问题,就得看拉普拉斯金字塔了。
下面给出OpenCV中pryUp和pryDown的用法
无论是放大还是缩小,图像都变得模糊了,这就是他的致命缺点。

新版

# 单个质心获取
import cv2
import numpy as np
# img01 = "S:\\AdobeppPS\\SKOO\\cc15.jpg"
img01 = "D:\\Pictures\\cscscs\\sc16.jpg"
img = cv2.imread(img01)
# convert image to grayscale image
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# convert the grayscale image to binary image
ret, thresh = cv2.threshold(gray_image, 127, 255, 0)
# calculate moments of binary image
M = cv2.moments(thresh)
# calculate x,y coordinate of center
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# put text and highlight the 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)
# display the image
cv2.imshow("Image", img)
print("质心坐标为:"+"(" +str(cX)+","+str(cY)+")")
cv2.waitKey(0)