相关文章推荐
玩命的炒粉  ·  【MATLAB】matlab ...·  1 年前    · 
细心的佛珠  ·  Webpack5 搭建 Vue3 + TS ...·  1 年前    · 
鬼畜的柚子  ·  cv mat resize image-掘金·  1 年前    · 

在前面的文章中,我们已经分析了SFR的算法原理与步骤,下面我们直接来分析源码,源码中主要的函数主要分为一下几个:

1、locate_centroids作用:定位每一行像素的矩心位置

unsigned short locate_centroids(double *farea, double *temp, double *shifts,unsigned short size_x, unsigned short size_y,double *offset)
 unsigned long i, j;
  double dt, dt1, dt2;
  /* Compute the first difference on each line. Interpolate to find the 
     centroid of the first derivatives. */
  //计算差分  计算矩心位置
  for (j = 0; j < size_y; j++) {
    dt = 0.0;
    dt1 = 0.0;
    for (i = 0; i < size_x-1; i++) {
      dt2 = farea[(j*(long)size_x)+(i+1)] - farea[(j*(long)size_x)+i]; 
      dt += dt2 * (double)i;
      dt1 += dt2;
	shifts[j] = dt / dt1;
	printf("=========\n");
	printf("%f\n", shifts[j]);
  /* check again to be sure we aren't too close to an edge on the corners. 
     If the black to white transition is closer than 2 pixels from either 
     side of the data box, return an error of 5; the calling program will 
     display an error message (the same one as if there were not a difference 
     between the left and right sides of the box ) */
  if (shifts[size_y-1] < 2  || size_x - shifts[size_y-1] < 2) {
    fprintf(stderr,"** WARNING: Edge comes too close to the ROI corners.\n");
   // return 5;
//防止矩心过于靠近图像的边界
  if (shifts[0] < 2 || size_x - shifts[0] < 2){
    fprintf(stderr,"** WARNING: Edge comes too close to the ROI corners.\n");
  //  return 5;
  /* Reference rows to the vertical centre of the data box */
  j = size_y/2;
  dt = shifts[j];
  for (i = 0; i < size_y; i++) {
    temp[i] = (double)i - (double)j;
    shifts[i] -= dt;
  *offset = dt;

2、fit函数:根据上面locate_centroid函数的结果,利用最小二乘法进行拟合,得到一条拟合后的质心直线。

unsigned short fit(unsigned long ndata, double *x, double *y, double *b, 
		   double *a, double *R2, double *avar, double *bvar)
  unsigned long i;
  double t,sxoss,syoss,sx=0.0,sy=0.0,st2=0.0;
  double ss,sst,sigdat,chi2,siga,sigb;
  *b=0.0;
  for ( i=0; i < ndata; i++ ) {
    sx += x[i];//x的叠加
    sy += y[i];//y的叠加
  //求平均值
  ss=(double)ndata;
  sxoss=sx/ss;   
  syoss=sy/ss;
  for ( i=0; i < ndata; i++ ) {
    t = x[i] - sxoss;  //
    st2 += t*t; //方差
    *b += t * y[i];  
  *b /= st2;         /* slope  *///斜率
  *a =(sy-sx*(*b))/ss; /* intercept *///截距
  siga=sqrt((1.0+sx*sx/(ss*st2))/ss);
  sigb=sqrt(1.0/st2);
  chi2=0.0;
  sst=0.0;
  for (i=0; i < ndata; i++) {
    chi2 += SQR( y[i] - (*a) - (*b) * x[i]); 
    sst += SQR( y[i] - syoss); 
  sigdat=sqrt(chi2/(ndata-2));
  siga *= sigdat;
  sigb *= sigdat;
  *R2 = 1.0 - chi2/sst;//拟合程度
  *avar = siga;
  *bvar = sigb;
  return 0;

3、bin_to_regular_xgrid的作用:进行四倍的超采样得到ESF

unsigned short bin_to_regular_xgrid(unsigned short alpha,//alpha->指的是超取样的倍数
				    double *edgex, double *Signal, 
				    double *AveEdge, long *counts,
				    unsigned short size_x,
				    unsigned short size_y)
  long i, j, k,bin_number;
  long bin_len;
  int nzeros;
  bin_len = size_x * alpha;  //扩大四倍
  for (i=0; i<bin_len; i++) {
    AveEdge[i] = 0;
    counts[i] = 0;
  for (i=0; i<(size_x*(long)size_y); i++) {
    bin_number = (long)floor((double)alpha*edgex[i]);//向下取整
    if (bin_number >= 0) {
      if (bin_number <= (bin_len - 1) ) {
        AveEdge[bin_number] = AveEdge[bin_number] + Signal[i];//把每一行的距离边缘x轴一样远的信号相加
        counts[bin_number] = (counts[bin_number])+1;//记录下对应位置有多少个信号相加
  nzeros = 0;
  for (i=0; i<bin_len; i++) {
    j = 0;
    k = 1;
    //感觉写的有点复杂
    if (counts[i] == 0) {
      nzeros++; //记录有多少个位置是空的,即没有信号
      //K的作用:因为这里的信号为0,找到后面第一个不为零的值,赋给当前这个零
      if (i == 0) {
        while (!j) { //当j==0时,表示此处的信号为0
          if (counts[i+k] != 0) {//第一行的元素
	    AveEdge[i] = AveEdge[i+k]/((double) counts[i+k]);
            j = 1;//充当flag。。。为啥不用布尔类型
          else k++;//直到找到第一个不为零的数字才会停止
      } else {
        while (!j && ((i-k) >= 0) ) { //j==0&&i-k>=0  j==0说明 counts[i]是0  i-k>0说明  k在i前面,找前面不为零的数值赋给AveEdge[i]
          if ( counts[i-k] != 0) {
	    AveEdge[i] = AveEdge[i-k];   /* Don't divide by counts since it already happened in previous iteration */
	    j = 1;
	  else k++;
        if ( (i-k) < 0 ) {//k>i,其实联合上面那段,就是:此处的counts[i]累加次数为零,所以AveEdge[i]也就是0,所以要找到附近一个不为零的值赋给AveEdge[i]
	  k = 1;
	  while (!j) {
	    if (counts[i+k] != 0) {
	      AveEdge[i] = AveEdge[i+k]/((double) counts[i+k]);
	      j = 1;
	    else k++;
      AveEdge[i] = (AveEdge[i])/ ((double) counts[i]);//如果此处不为零,直接就求个平均值
  if (nzeros > 0) {//提示信息
    fprintf(stderr, "\nWARNING: %d Zero counts found during projection binning.\n", nzeros);
    fprintf(stderr, "The edge angle may be large, or you may need more lines of data.\n\n");
  return nzeros;

好了,今天先写到这,接下来有空会把接下来几个函数补上。

欢迎关注我的个人公众号,这里有更多好康的喔~

在前面的文章中,我们已经分析了SFR的算法原理与步骤,下面我们直接来分析源码,源码中主要的函数主要分为一下几个:1、locate_centroids作用:定位每一行像素的矩心位置unsigned short locate_centroids(double *farea, double *temp, double *shifts,unsigned short size_x, unsigne...
分辨率(解析度,Resolution) 分辨率使我们经常听到的一个词,它代表了图像的精细程度,也代表了图像的大小。分辨率决定了在这种大小下,输出信号是否能够包含足够多的信息来获取所需的细节。这个参数和图片本身是否锐利或图片是否没有干扰(比如彩色摩尔纹)关系不大。 在ISO 12233中,分辨率被定义为衡量一个摄像机系统或摄像机系统的一个部件描绘图像细节的能。 通常我们所说的分辨率一般都会以横向像素个数和纵向像素个数的乘积表达,比如1920*1080, ...
图像解析算法SFRSpatial Frequency Response)原理分析(一)中,我们已经分析SFR的前四个步骤,接下来,我们继续讨论以下的五个步骤 4、重新定位ROI,获得ESF 5、对获得的ESF进行四倍超采样 6、通过差分运算获得LSF 7、对LSF应用汉明窗 8、进行DFT运算 4、重新定位ROI,获得ESF 这一步其实比较复杂,我也不确定在我的讲述之...
图像解析算法SFRSpatial Frequency Response)概念理解一文中,我们已经讲解了在阅读SFR源码前必须了解的概念,下面我们来讲解一下,SFR算法的计算具体流程,然后结合源码进行分析, 获取计算公式。 先来看图,直观感受一下吧: 可以看到,SFR的具体步骤就是上面的九大步骤,箭头中对应的是每一步执行前后对应的输入和输出。 总结如下: 0、获取垂直斜边的ROI...
需要提前装好MinwG,在环境变量path里添加MinwG的bin路径,并配置好gcc、g++、mingw32-make。 起初还尝试在vs2017里进行编译,发现导入这个包那个库(比如tiff),改这个句那个词的,都不太好使啊。然后瞅见makefile,才想起可以在cmd里gcc编译(其实编译过程并不需要makefile,这就表示,不需要make工具,单凭gcc语句也是可以编译的,想一想也是,毕竟make工具调用makefile编译,而makefile里就包含gcc的语句嘛),具体步骤如下: 1、win+
sfrmat is a Matlab function that provides a spatial frequency response* (SFR) from a digital image file containing a slanted-edge feature. The specific edge-gradient algorithm follows the intent of the standard ISO 12233, developed by Technical Committee ISI/TC 42, for resolution measurements for electronic still pictorial cameras.
1.准备未经过sharpen&gamma处理的图像,因为gamma将数据进行了非线性处理,sharpen对边缘进行了overshoot处理。最好是原始bayer数据(democode中我使用的是bayer数据转成了bmp格式图片)。提取包含斜边的区域ROI,转化为YVU,我们只用Y通道数据就够了。 (备注:当然你也可以对sharpen...
Imatest SFRSpatial Frequency Response算法是一种测试图像分辨率的方法。这个算法是由Imatest公司提出和开发的,被广泛应用于图像质量评价领域。 Imatest SFR算法通过分析图像中的特定频率线条的模糊程度来评估图像的分辨率能。该算法首先通过计算线条的对比度和峰值位置来确定图像的清晰度和锐度,然后根据模糊度函数将图像的分辨率能进行量化。 Imatest SFR算法的优点是精确度高、稳定性强。它采用了自动化的分析方法,可以快速准确地评估图像的分辨率能,避免了主观因素的干扰。此外,该算法还可以基于不同的测试标准进行定制化设置,以适应不同的应用需求。 Imatest SFR算法的应用范围非常广泛。它可以用于评估相机、手机、显示器等各类图像采集和显示设备的分辨率能。在生产线上,可以使用该算法进行质量控制和检测。在研发过程中,可以利用该算法来优化图像处理算法和参数设置,以提升图像的清晰度和细节还原能。 总之,Imatest SFR算法是一种强大而高效的图像分辨率评估方法。它能够快速准确地量化图像的分辨率能,为图像质量评价和优化提供了有的工具和指导。
error: (-215:Assertion failed) src_depth != CV_16F && src_depth != CV_32S in function 'convertToShow 22451