数字图像处理基于Python如何数一张图片的物体有多少个?

数字图像处理基于Python如何数一张图片的物体有多少个?,第1张

如果要使用Python进行数字图像处理,可以使用OpenCV库来数一张图片的物体有多少个。

下面是一个简单的例子,可以使用OpenCV库来数一张图片中的小球数量:

import cv2

# 读取图片

img = cv2.imread("balls.jpg")

# 将图片转换为灰度图

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 使用阈值分割法,得到二值图

thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)[1]

# 寻找图像中的轮廓

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cnts = imutils.grab_contours(cnts)

# 显示图像中的轮廓数量

print("图像中的轮廓数量:{}".format(len(cnts)))

ImageJ可以。

ImageJ是一款常用的生物图像处理软件,通过软件打开要计数的图片,将彩色图片转换为8-bit格式,调整阈值,将所有胞核变为纯黑,背景变为纯白。拖动滑块时,红色显示即为我们所要计数的细胞,可自由调整,以排除较小的细胞杂质。最后到了分析计数步骤,点击“Analyze Particles”后,可出现d窗,d窗里,需要设置“Size”范围,以排除杂质。一般我们最小Size值设置为50-100范围内均可,每次实验计数时最好保持最小Size值一致,点击“OK”,即可出现细胞数量。

用ImageJ的来为图片上的粒子计数,这里的粒子可以是细胞、克隆、孢子、菌落、病斑等。

可以参考下面的程序,其中bitCount!=8 &&bitCount!=24指的就是8位与24位

//BMP与IplImage相互转换

///////////////////////////////头文件bmp2ipl.h

//bmp2ipl.h

#ifndef BMP2IPL_H

#define BMP2IPL_H

class BMP {

public:

BMP():bmpData(NULL) {

memset(&biHeader, 0, sizeof(biHeader))

}

BMP(const BMP &img)

BMP(const IplImage &img)

BMP(int width, int height, int bitCount)

~BMP(){ delete [] bmpData}

bool CreateImage(const BITMAPINFOHEADER &biHeader)

//Export

IplImage * BMP2Ipl()

//void Show(HWND hWnd, int nID)

//void Show(CDC *pDC, CRect &rect)

//void Show(HWND hWnd)

void ReSize(int newW, int newH)

private:

void CopyData(char *dest, const char *src, int dataByteSize,

bool isConvert, int height)

// isConvert=true 进行顶左和底左之间的转换(顶左到底左或底左到顶左),否则不转换

// biSizeImage may be set to zero for BI_RGB bitmaps, so calculate it.

int ImgSize() {

return ( biHeader.biHeight * ((biHeader.biWidth * biHeader.biBitCount / 8 + 3) &(-4)))

}

public:

void Clear()

BITMAPINFOHEADER biHeader

unsigned char * bmpData

}

#endif

/////////////////////////////////////////////////////////////////////实现文件bmp2ipl.cpp

#include "bmp2ipl.h"

/**************************************************************************************************

* *

* NOTE: *

* Only use the "8 bit, 1 or 3 channels" image, the BitMap use LowerLeft (底左), *

* the IplImage use TopLeft (顶左) *

* IplImage: *

* nChannels = 1 or 3 number of channels *

* depth = IPL_DEPTH_8U pixel depth (8 bit), IPL_DEPTH_8U=8 *

* dataOrder = 0 交叉存取颜色通道 *

* origin = IPL_ORIGIN_TL 图像数据保存形式,IPL_ORIGIN_BL底左结构, IPL_ORIGIN_TL顶左结构 *

* align = 4 行数据对齐方式,保证下一行数据从整4字节位置开始 *

* width *

* height *

* widthStep 图像数据行大小,单位字节 *

* imageSize 图像数据大小(=height*widthStep),单位字节 *

* imageData 指向图像数据区,char * *

* BITMAPINFOHEADER: *

* biSize Specifies the number of bytes required by the structure *

* biWidth *

* biHeight(>0) biHeight>0底左结构;biHeight<0顶左结构 *

* biPlanes = 1 Specifies the number of planes for the target device. This value *

* must be set to 1. *

* biBitCount =8 or 24 bits-per-pixel,8-(pixelDepth=8,channels=1), *

* 24-(pixelDepth=8,channels=3) *

* biCompression = BI_RGB An uncompressed format *

* biSizeImage Specifies the size, in bytes, of the image.This may be set to zero *

* for BI_RGB bitmaps. *

* biXPelsPerMeter = 0 *

* biYPelsPerMeter = 0 *

* biClrUsed = 0 *

* biClrImportant = 0 *

* *

***************************************************************************************************/

BMP::BMP(const BMP &img)

{

if(!IsSupport(img)) {

BMP()

return

}

//biHeader = img.biHeader

PBITMAPINFOHEADER pBmpH = (PBITMAPINFOHEADER)&img.biHeader

memcpy(&biHeader, pBmpH, sizeof(BITMAPINFOHEADER))

biHeader.biSizeImage = ImgSize()

bool isLowerLeft = biHeader.biHeight>0

//int rowSize=0

if(!isLowerLeft) biHeader.biHeight=-biHeader.biHeight

if(bmpData!=NULL) delete[] bmpData

bmpData = new unsigned char [biHeader.biSizeImage]

//memcpy(bmpData, img.bmpData, img.biHeader.biSizeImage)

CopyData((char *)bmpData, (char*)img.bmpData, biHeader.biSizeImage,

!isLowerLeft, biHeader.biHeight)

}

BMP::BMP(const IplImage &img) {

if(!IsSupport(img)) {

BMP()

return

}

bool isTopLeft = (img.origin == IPL_ORIGIN_TL)

biHeader.biSize = sizeof(BITMAPINFOHEADER)

biHeader.biWidth = img.width

biHeader.biHeight = img.height

biHeader.biPlanes = 1

biHeader.biBitCount = img.depth * img.nChannels

biHeader.biCompression = BI_RGB

biHeader.biSizeImage = img.imageSize

biHeader.biXPelsPerMeter = 0

biHeader.biYPelsPerMeter = 0

biHeader.biClrUsed = 0

biHeader.biClrImportant = 0

if(bmpData!=NULL) delete[] bmpData

bmpData = new unsigned char [img.imageSize]

//memcpy(bmpData, img.ImageData, img.imageSize)

CopyData((char*)bmpData, (char*)img.imageData, img.imageSize,

isTopLeft, img.height)

/*int i,j

CvScalar s

for(i=0i<img.widthi++)

for(j=0j<img.heightj++){

s=cvGet2D(&img,i,j)

}

*/

}

BMP::BMP(int width, int height, int bitCount) {

if(bitCount!=8 &&bitCount!=24) return

biHeader.biSize = sizeof(BITMAPINFOHEADER)

biHeader.biWidth = width

biHeader.biHeight = height

biHeader.biPlanes = 1

biHeader.biBitCount = bitCount

biHeader.biCompression = BI_RGB

biHeader.biSizeImage = ImgSize()

biHeader.biXPelsPerMeter = 0

biHeader.biYPelsPerMeter = 0

biHeader.biClrUsed = 0

biHeader.biClrImportant = 0

if(bmpData!=NULL) delete[] bmpData

bmpData = new unsigned char [biHeader.biSizeImage]

Clear()

}

// dest: the destination image

// dataByteSize: the Source image

// height: source image height

void BMP::CopyData(char *dest, const char *src, int dataByteSize,

bool isConvert, int height) {

char * p = dest

if(!isConvert) {

memcpy(dest, src, dataByteSize)

return

}

if(height<=0) return

//int height = dataByteSize/rowByteSize

int rowByteSize = dataByteSize / height

src = src + dataByteSize - rowByteSize

for(int i=0i<heighti++) {

memcpy(dest, src, rowByteSize)

dest += rowByteSize

src -= rowByteSize

}

}

IplImage * BMP::BMP2Ipl() {

if(!IsSupport(*this)) return NULL

IplImage *iplImg

int height

bool isLowerLeft = biHeader.biHeight>0

height = (biHeader.biHeight>0) ? biHeader.biHeight : -biHeader.biHeight

iplImg = cvCreateImage( cvSize(biHeader.biWidth, height), IPL_DEPTH_8U, biHeader.biBitCount / 8)

//iplImg = cvCreateImageHeader( cvSize(biHeader.biWidth, height), IPL_DEPTH_8U, biHeader.biBitCount / 8)

//cvSetData(iplImg,(char*)bmpData,biHeader.biSizeImage/height)

CopyData( iplImg->imageData, (char*)bmpData, biHeader.biSizeImage,

isLowerLeft, height)

/*int i,j

CvScalar s

int channels=biHeader.biBitCount / 8

int step=(biHeader.biWidth*channels+3) &-4

int loc=0

for(i=0i<iplImg->heighti++){

for(j=0j<iplImg->widthj++){

loc=i*step + j*channels

s.val[0]=bmpData[loc]

if(channels==3){

s.val[1]=bmpData[loc+1]

s.val[2]=bmpData[loc+2]

}

cvSet2D(iplImg,i,j,s)

}

}*/

return iplImg

}

void BMP::Clear() {

if(bmpData == NULL) return

memset(bmpData, 0, ImgSize())

}

void BMP::ReSize(int newW, int newH) {

biHeader.biWidth = newW

biHeader.biHeight = newH

biHeader.biSizeImage = ImgSize()

if(bmpData!=NULL) delete[] bmpData

bmpData = new unsigned char [biHeader.biSizeImage]

Clear()

}

bool BMP::CreateImage(const BITMAPINFOHEADER &bih) {

memset(&biHeader,0,sizeof(BITMAPINFOHEADER))

delete[] bmpData

bmpData = NULL

memcpy(&biHeader, &bih, sizeof(BITMAPINFOHEADER))

biHeader.biSizeImage = ImgSize()

bmpData = new unsigned char [ biHeader.biSizeImage ]

if(bmpData == NULL) return false

else{

Clear()

return true

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11226283.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存