前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于widthStep造成的问题

关于widthStep造成的问题

作者头像
全栈程序员站长
发布2022-06-28 14:19:42
5680
发布2022-06-28 14:19:42
举报
文章被收录于专栏:全栈程序员必看

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

最近遇到一个很奇怪的问题,一直没有解决,就是在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:异常

源代码:

// 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:正常

// 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.cn/132961.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年6月9,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档