❶ 你好,怎么提取种子的特征数据啊,有好的方法吗
提取种子的特征数据时种子颗粒饱满、充实,其内营养物质就相对的较多,相应的发芽率高,发芽整齐,植株生命力旺盛。
而种子的大小、颗粒饱满程度用以下方法来鉴定:
我们可以用千粒重来判定一类种子的大小即饱满程度是一种很简便的方法。而千粒重的测定需要借助种子数粒仪和一定精度的天平。
种子千粒重是指在一定的环境条件下1000粒种子的重量。
其测定方法为从样品种子中扦样抽取1000粒种子,在扦样前先对种子进行净度分析,然后称重,重复两次以上,再求其平均值,得到的参数就是千粒重。此间,1000粒种子需要电子自动数粒仪来进行数粒。
这里需要注意几点:大、中粒子对天平的要求为感量在0.1g,而10g以下的种子对天平的要求更高些,感量需在0.01g.试样质量≤1g,称至4位小数;1-9.99g的称重至3位小数;10-999.9g的称重至2位小数;1000g以上称重至整数。如果前后两次测量差值不超过5%,则可停止称重,将其两份试样的重量平均,得到种子的千粒重。如果超过允许误差,则需再次进行数粒、称重,直到两次称重在允许误差之内,然后再计算得出种子的千粒重。
❷ 轮廓提取的算法有哪些
LZ你问的问题太宽泛了,不同对象有不同的处理方法。
可以参考一下广义Hough变换、Haar及Canny这些,看看对你的研究有没有帮助。
❸ 自动提取像点坐标的算法
不知道你学的什么.我是学C++的.按照编程的思路来说,一般遇到这样的问题,我们都会逐像素横向check,第一次遇到白点后记录,然后继续,横向遇到黑点停止,然后计算两点间的像素,得到直径,就可以得到中点了,然后继续再横向check直到整个图完结,希望能帮到你
❹ 提取图像轮廓的问题
matlab自带的那几个边界提取函数好像都只能提取出原图像的边界,我帮你改了一下,你把bw=bwperim(f);(包括这句)以后的代码都去掉,用我给你写的这个,就可以提取出图像上下左右边界的坐标了。你可以输出一下看看是否正确
[x,y]=size(f);
for i=1:x
f(i,2)=0;
f(i,y-1)=0;
end
for j=1:y
f(2,j)=0;
f(x-1,j)=0;
end
[m1,n1]=find(f);
maxx=max(m1); %%最大x值
maxy=max(n1); %%最大y值
minx=min(m1); %%最小x值
miny=min(n1); %%最小y值
希望对你能有所帮助。
❺ 请问哪位高手帮忙解答:边缘检测和轮廓提取是一回事吗如果不是,请问区别在哪呢谢谢,急求答案
不一样的。轮廓提取主要是从一个种子点,用搜索的方法找到闭合的轮廓。边缘检测主要是根据图像上的边缘在像素上变化很大的,用微分的方法,找到边缘。一般边缘检测后都要做二值化处理,把边缘和背景分割出来。轮廓就不用二值化,因为搜索的时候已经将得到的轮廓存起来了~
❻ 请教基于opencv的轮廓提取问题
先灰度化->二值化,弄成二值图,你就会提取了
给你个例子
C/C++ code
#include <stdio.h>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
using namespace std;
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")
struct Position
{
int x,y;
};
double per[256];// 保存灰度概率
IplImage *FindCountours(IplImage* src,IplImage *pContourImg);
int ImageStretchByHistogram(IplImage *src,IplImage *dst);
IplImage* Hist_Equalization(IplImage *srcimg);
void proBorder(IplImage *src); // 边界的处理
void GetBackImage(IplImage* src,IplImage* src_back);
void Threshold(IplImage *src);
int GetThreshold(double *const prob);
void Getprobability(IplImage *src);
double Eccentricity(IplImage *src);
void main()
{
//IplImage * src = cvLoadImage("C:\\image19\\A634.jpg",-1);//灰度图的方式载入
IplImage * src = cvLoadImage("C:\\image19\\A857.jpg",-1);
IplImage * dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
IplImage *src_back = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,src->nChannels);
GetBackImage(src,src_back);
dst = FindCountours(src_back,dst);
cvNamedWindow("test",CV_WINDOW_AUTOSIZE);
cvShowImage("test",dst);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&dst);
}
void GetBackImage(IplImage* src,IplImage* src_back)
{
//cvCvtColor(src,src,CV_RGB2GRAY);//灰度化
IplImage *tmp = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
// 创建结构元素
IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);
//用该结构对源图象进行数学形态学的开操作后,估计背景亮度
cvErode(src,tmp,element,9);
//使用任意结构元素腐蚀图像
cvDilate(tmp,src_back, element,9);
//使用任意结构元素膨胀图像
}
IplImage *FindCountours(IplImage* src,IplImage *pContourImg)
{
CvMemStorage *storage = cvCreateMemStorage(0); //提取轮廓需要的储存容量为默认KB
CvSeq * pcontour = 0; //提取轮廓的序列指针
IplImage *temp = cvCreateImage(cvGetSize(src),src->depth,1);
//cvSmooth(src,temp,CV_GAUSSIAN,3,1,0);
cvSmooth(src,src,CV_GAUSSIAN,3,1,0);//平滑处理
cvCvtColor(src,temp,CV_RGB2GRAY);//灰度化
Getprobability(temp);
printf("最好的阈值:%d\n",GetThreshold(per));
//Threshold(temp);
proBorder(temp);
cvThreshold(temp,temp,GetThreshold(per),255,CV_THRESH_BINARY_INV);
int contoursNum = 0; // 轮廓数量
//int mode = CV_RETR_LIST;
int mode = CV_RETR_EXTERNAL;// 提取最外层轮廓
contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),mode,CV_CHAIN_APPROX_NONE);
// contoursNum = cvFindContours(temp,storage,&pcontour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
//二值图, 得到轮廓存储,轮廓指针序列,header_size,提取模式,逼近方法
CvScalar externalColor;// 保存颜色值
CvScalar holeColor;
//————–画轮廓—————-//
for (; pcontour != 0; pcontour=pcontour -> h_next)
{
//holeColor=CV_RGB(rand()&255,rand()&255,rand()&255);
//externalColor=CV_RGB(rand()&255,rand()&255,rand()&255);
CvRect r = ((CvContour *)pcontour)->rect;
if(r.height * r.width < 800)
{
holeColor=CV_RGB(0,0,0);
externalColor=CV_RGB(0,0,0);
cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);
}
else
{
//取得轮廓面积
double contArea = fabs(cvContourArea(pcontour,CV_WHOLE_SEQ));
//取得轮廓长度
double contLenth = cvArcLength(pcontour,CV_WHOLE_SEQ,-1);
// 圆形度
double contcircularity = contLenth * contLenth / contArea;
double pxl =Eccentricity(temp);
cout<<"面积为:"<<contArea<<endl;
cout<<"周长为:"<<contLenth<<endl;
cout<<"圆形度为:"<<contcircularity<<endl;
holeColor=CV_RGB(255,255,255);
externalColor=CV_RGB(255,255,255);
cvDrawContours(pContourImg,pcontour,externalColor,holeColor,1,1,8);
}
}
//IplConvKernel *element = cvCreateStructuringElementEx( 2, 2, 0, 0, CV_SHAPE_ELLIPSE,0);
//cvDilate(pContourImg,pContourImg, element,9);
return pContourImg;
}
double Eccentricity(IplImage *src)//偏心率
{
Position pos[4];
int width = src->width;
int height = src->height;
int i,j;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
int pixel = (int)cvGet2D(src,i,j).val[0];
if(pixel != 0)
{
pos[0].x = j;
pos[0].y = i;//
goto s;
}
}
}
s:
for(i = height – 1; i >= 0; i–)
{
for(j = 0; j < width ; j++)
{
int pixel = (int)cvGet2D(src,i,j).val[0];
if(pixel != 0)
{
pos[1].x = j;
pos[1].y = i;//
goto w;
}
}
}
w:
for(i = 0 ; i < width ; i++)
{
for(j = 0;j < height; j++)
{
int pixel = (int)cvGet2D(src,j,i).val[0];
if(pixel != 0)
{
pos[2].x = j;//
pos[2].y = i;
goto e;
}
}
}
e:
for(i = width – 1; i >= 0; i–)
{
for(j = 0 ; j < height ; j++)
{
int pixel = (int)cvGet2D(src,j,i).val[0];
if(pixel != 0)
{
pos[3].x = j;//
pos[3].y = i;
goto f;
}
}
}
f:
int l_dis = abs(pos[0].y – pos[1].y);
int s_dis = abs(pos[2].x – pos[3].x);
int tmp_dis;
if(l_dis > s_dis)
{
printf("偏心率:%f\n",l_dis*1.0/s_dis);
}
else
{
tmp_dis = l_dis;
l_dis = s_dis;
s_dis = tmp_dis;
printf("偏心率:%f\n",l_dis*1.0/s_dis);
}
return 0;
}
void Getprobability(IplImage *src)
{
memset(per,0,sizeof(per));
int width = src->width;
int height = src->height;
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
per[(int)cvGet2D(src,i,j).val[0]]++;
}
}
int PixlNum = width * height;
for(i = 0; i < 256; i++)
per[i] = per[i] / PixlNum;
}
int GetThreshold(double *const prob)
{
int threshold = 0;
double maxf = 0;
for (int crrctThrshld = 1; crrctThrshld < 256 – 1; ++crrctThrshld) {
double W0 = 0, W1 = 0, U0 = 0, U1 = 0;
int i = 0;
for (i = 0; i <= crrctThrshld; ++i) {
U0 += i * prob[i];
W0 += prob[i];
}
for (; i < 256; ++i) {
U1 += i * prob[i];
W1 += prob[i];
}
if (W1 == 0 || W1 == 0)
continue;
U0 /= W0;
U1 /= W1;
double D0 = 0, D1= 0;
for (i = 0; i <= crrctThrshld; ++i)
D0 += pow((i – U0) * prob[i], 2.0);
for (; i < 256; ++i)
D1 += pow((i – U1) * prob[i], 2.0);
D0 /= W0;
D1 /= W1;
double Dw = pow(D0, 2.0) * W0 + pow(D1, 2.0) * W1;
double Db = W0 * W1 * pow((U1 – U0), 2.0);
double f = Db / (Db + Dw);
if (maxf < f) {
maxf = f;
threshold = crrctThrshld;
}
}
return threshold;
}
void proBorder(IplImage *src) // 边界的处理
{
int i,j;
int height = src->height;
int width = src->width;
int N = 100;
for(i = 0; i < N * width; i += width) // i表示向下走左上角
{
for(j = 0; j < N ; j++)
{
int index = i + j;
src->imageData[index] = (char)255;
}
}
int NN = 150;
int sw = width * (height – NN);// 左下角 三角形
int t = 1;
for(i = sw; i < sw + NN * width; i += width,t++)
{
for(j = 0; j < t; j++)
{
int index = i + j;
src->imageData[index] = (char)255;
}
}
int se = (height – NN – 1) * width; // 右下角
t = 0;
for(i = se; i < width * height ; i += width,t++)
{
for(j = 0; j < t; j++)
{
int index = i + j – t;
src->imageData[index] = (char)255;
}
}
int ne = width – NN; // 右上角 三角形剪切
t = 0;
for(i = ne; i < NN * width; i +=width,t++)
{
for(j = 0; j < NN – t; j++)
{
int index = i + j + t;
src->imageData[index] = (char)255;
}
}
}
void Threshold(IplImage *src)
{
int width = src->width;
int height = src->height;
float minpixel = cvGet2D(src,0,0).val[0];
float maxpixel = cvGet2D(src,0,0).val[0];
CvScalar s;
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
s = cvGet2D(src,i,j);
if(s.val[0] > maxpixel)
maxpixel = s.val[0];
if(s.val[0] < minpixel)
minpixel = s.val[0];
}
}
float firstgrey = (maxpixel + minpixel) / 2;
printf("%f\n",firstgrey);
float lastgrey;
float sum1 = 0,sum2 = 0;
int num1 = 0,num2 = 0;
int result = 0;
❼ 如何提取轮廓上每个点的坐标
mode = CV_RETR_LIST;
contours_num=cvFindContours(preimg, storage, &contours, sizeof(CvContour), mode, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
for (;contours!=0;contours=contours->h_next)
{
onetourlength = contour->total;
CvPoint *points = (CvPoint *)malloc(sizeof(CvPoint) * onetourlength);
//printf("seqlength:%dn",seqlength);
CvSeqReader reader;
CvPoint pt = cvPoint(0,0);
cvStartReadSeq(contour,&reader);
for(int i = 0 ;i < onetourlength; i++){
CV_READ_SEQ_ELEM(pt,reader);
points[i] = pt;
cvSeqPush(allpointsSeq,&pt);
}
cvPolyLine(image,&points,&onetourlength,1,0,CV_RGB(0,255,0),2,8,0);
}