关于widthStep造成的问题

关于widthStep造成的问题最近遇到一个很奇怪的问题,一直没有解决,就是在A图像中设置一个ROI,将其clone给B,然后对B进行二值化,输入为B,输出为C,这时二值化完后的图像C跟ROI区域的图像区域不同。通过查看发现罪魁祸首是widthStep变了。无意中解决了这个问题,做法如下:方法1:就是在A图像中设置一个ROI,将其clone给B,新建一个C,大小、位数和通道数同B,将Bclone给C,然后对C进行

大家好,又见面了,我是你们的朋友全栈君。

最近遇到一个很奇怪的问题,一直没有解决,就是在A图像中设置一个ROI,将其clone给B,然后对B进行二值化,输入

为B,输出为C,这时二值化完后的图像C跟ROI区域的图像区域不同。通过查看发现罪魁祸首是widthStep变了。

无意中解决了这个问题,做法如下:

方法1:就是在A图像中设置一个ROI,将其clone给B,新建一个C,大小、位数和通道数同B,将B clone给C,然后对C进行

InToIn的二值化操作,这个问题就解决了。

方法2:只拿二值化的阈值,在otsu函数里面不进行二值化操作,然后调用cvThreshold函数进行二值化。

现象1:异常

关于widthStep造成的问题

源代码:

// Otsu.cpp : Defines the entry point for the console application.
//

#include “stdafx.h”
#include <iostream.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <windows.h>

int height;int width;
int otsu(IplImage* A, IplImage* B)
{

long N = height * width;
int h[256];
double p[256],u[256],w[256];
for(int i = 0; i < 256; i++)  
{   
h[i] = 0;   
p[i] = 0;   
u[i] = 0;    
w[i] = 0;  
}

for(i = 0; i < height; i++)   
for(int j = 0; j < width; j++)   
for(int k = 0; k < 256; k++)    
{      
if(((uchar*)(A->imageData + A->widthStep*i))[j] == k)    
h[k]++;  
}

for(i = 0; i < 256; i++)   
p[i] = h[i] / double(N);

int T = 0;   
double uT,thegma2fang; 
double thegma2fang_max = -10000;

for(int k = 0; k < 256; k++)  
{    
uT = 0;     
for(i = 0; i <= k; i++) 
{     
u[k] += i*p[i];   
w[k] += p[i];    
}

for(i = 0; i < 256; i++)    
uT += i*p[i];     
thegma2fang = (uT*w[k] – u[k])*(uT*w[k] – u[k]) / (w[k]*(1-w[k]));
if(thegma2fang > thegma2fang_max)  
{     
thegma2fang_max = thegma2fang;    
T = k;  
}  
}

for(i = 0; i < height; i++)  //根据最佳阈值,对原图像进行处理二值化处理    
for(int j = 0; j < width; j++)      
if(((uchar*)(A->imageData + A->widthStep*i))[j] > T)   
((uchar*)(B->imageData + B->widthStep*i))[j] = 255;   
else       
((uchar*)(B->imageData + B->widthStep*i))[j] = 0;

return T;
}

int main(int argc, char** argv)

const char* filename = argc >= 2 ?argv[1] : “lena.jpg”;  
IplImage* source = cvLoadImage( filename, 0 );
int Th;

height = source->height;   
width = source->width;
CvRect rect;
rect.x=50;
rect.y=30;
rect.width=height/2;
rect.height=width/2;
IplImage *roi = cvCreateImage(cvSize(rect.width,rect.height),IPL_DEPTH_8U,1); 
IplImage *bw = cvCreateImage(cvSize(rect.width,rect.height),IPL_DEPTH_8U,1);

cvSetImageROI(source,rect);
roi=cvCloneImage(source);
cvResetImageROI(source);

Th = otsu(roi,bw);

printf(“Th=%d\n”,Th);
cvNamedWindow( “Resource”, 1 );   
cvShowImage( “Resource”, source ); 
cvNamedWindow( “Result”, 1 );  
cvShowImage( “Result”, roi); 
cvNamedWindow( “BW”, 1 );  
cvShowImage( “BW”, bw); 
cvWaitKey(0);
return 0;
}

现象2:正常

关于widthStep造成的问题

// Otsu.cpp : Defines the entry point for the console application.
//

#include “stdafx.h”
#include <iostream.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <windows.h>

int height;int width;
int otsu(IplImage* A, IplImage* B)
{

long N = height * width;
int h[256];
double p[256],u[256],w[256];
for(int i = 0; i < 256; i++)  
{   
h[i] = 0;   
p[i] = 0;   
u[i] = 0;    
w[i] = 0;  
}

for(i = 0; i < height; i++)   
for(int j = 0; j < width; j++)   
for(int k = 0; k < 256; k++)    
{      
if(((uchar*)(A->imageData + A->widthStep*i))[j] == k)    
h[k]++;  
}

for(i = 0; i < 256; i++)   
p[i] = h[i] / double(N);

int T = 0;   
double uT,thegma2fang; 
double thegma2fang_max = -10000;

for(int k = 0; k < 256; k++)  
{    
uT = 0;     
for(i = 0; i <= k; i++) 
{     
u[k] += i*p[i];   
w[k] += p[i];    
}

for(i = 0; i < 256; i++)    
uT += i*p[i];     
thegma2fang = (uT*w[k] – u[k])*(uT*w[k] – u[k]) / (w[k]*(1-w[k]));
if(thegma2fang > thegma2fang_max)  
{     
thegma2fang_max = thegma2fang;    
T = k;  
}  
}
return T;
}

int main(int argc, char** argv)

const char* filename = argc >= 2 ?argv[1] : “lena.jpg”;  
IplImage* source = cvLoadImage( filename, 0 );
int Th;

height = source->height;   
width = source->width;
CvRect rect;
rect.x=0;
rect.y=0;
rect.width=height/2;
rect.height=width/2;
IplImage *roi = cvCreateImage(cvSize(rect.width,rect.height),IPL_DEPTH_8U,1); 
IplImage *bw = cvCreateImage(cvSize(rect.width,rect.height),IPL_DEPTH_8U,1);

cvSetImageROI(source,rect);
roi=cvCloneImage(source);
cvResetImageROI(source);

bw = cvCloneImage(roi);
Th = otsu(bw,bw);
cvThreshold(roi,bw,Th,255,CV_THRESH_BINARY);

printf(“roi->widthStep=%d,bw->widthStep=%d\n”,roi->widthStep,bw->widthStep);
printf(“Th=%d\n”,Th);
cvNamedWindow( “Resource”, 1 );   
cvShowImage( “Resource”, source );
cvNamedWindow( “Result”, 1 );  
cvShowImage( “Result”, roi);
cvNamedWindow( “BW”, 1 );  
cvShowImage( “BW”, bw); 
cvWaitKey(0);
return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132961.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月9日 下午11:36
下一篇 2022年6月9日 下午11:36


相关推荐

  • Ldap服务器搭建流程

    Ldap服务器搭建流程之前搭建了个Ldap服务器,今天想要再另一台机器上搭建的时候发现很多地方还是会遇到坑,于是将搭建过程梳理记录下来,避免以后再遇到坑一、安装配置ldap1、安装ldap    yuminstall-yopenldap*2、拷贝配置文件    cp/usr/share/openldap-servers/slapd.conf.obsolete/etc/openldap/slapd…

    2022年5月14日
    44
  • 步进电机S(SigMoid)曲线加减速【查表法】

    步进电机S(SigMoid)曲线加减速【查表法】首先感谢以下博客的博主提供的参考公式 https blog csdn net pengzhihui20 article details locationNum 6 首先在本设计中采用的步进电机控制方案为 单片机 16 位定时器比较匹配中断 最好是 16 位及其以上 步进电机驱动 42 步进电机 较高的定时器精度能够实现更好的控制 在步进电机控制中往

    2026年3月17日
    2
  • Manus AI多语言手写识别技术全解析:从模型架构到实战部署

    Manus AI多语言手写识别技术全解析:从模型架构到实战部署

    2026年3月15日
    2
  • RK键盘说明书

    RK键盘说明书图片说明多媒体快捷键 Win 系统 Mac 系统 Win 系统 Mac 系统 FN F1 我的电脑屏幕亮度 FN F7 播放 暂停上一首 FN F2 浏览器屏幕亮度 FN F8 停止播放 暂停 FN F3 邮件多任务切换 FN F9 音量 下一首 FN F4 播放所有任务 FN F10 音量 静音 FN F5 上一首笔记本亮度 FN F11 静音音量 FN F6 下一首笔记本亮度 FN F12 计算器音量 功能键一览 Fn 1 7

    2026年3月16日
    2
  • 重定向和转发的区别及应用_重定向是什么意思

    重定向和转发的区别及应用_重定向是什么意思请求转发:客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,它要调用getRequestDispacther()方法,把请求转发给指定的student_list.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完成的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在stude…

    2025年10月8日
    5
  • 项目半夜凌晨宕机,报错Invalid character found in method name. HTTP method names must be tokens|the HTTP protoco[通俗易懂]

    项目半夜凌晨宕机,报错Invalid character found in method name. HTTP method names must be tokens|the HTTP protoco[通俗易懂]这几天项目总是在凌晨挂机,查看日志发现以下错误:Http11Processor-ErrorparsingHTTPrequestheaderNote:furtheroccurrencesofHTTPheaderparsingerrorswillbeloggedatDEBUGlevel.java.lang.IllegalArgumentExceptio…

    2022年7月15日
    26

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号