问题描述
- 求大神帮忙把代码改成调用opencv库的,谢谢。
-
include
using namespace std;
#include //需要使用堆栈,对堆栈进行操作
#include "conio.h"include "viLib.h" // 包含头文件
pragma comment( lib, "viLib.lib" ) // 包含viLib.lib库
include "viImage.h" // 包含头文件
pragma comment( lib, "viImage.lib" )
struct SplitArea
{
unsigned int w; // 分裂块图像的宽度
unsigned int h; // 分裂块图像的高度
unsigned int left; //相对源图像数据的偏移宽度
unsigned int top; // 相对源图像数据的偏移高度
};
void areaSplitCombine(unsigned char *srcImage, // 源图像数据
unsigned int Width, // 源图像的宽度
unsigned int Heigh) // 相对源图像数据的偏移高度
{
//初始区域压栈即整幅图片压栈
stack MyStack;
SplitArea splitarea;
splitarea.w = Width;
splitarea.h = Heigh;
splitarea.left = 0;
splitarea.top = 0;
MyStack.push(splitarea); //原始图像的区域信息栈
while(!MyStack.empty())
{
//区域出栈
splitarea = MyStack.top();
MyStack.pop();
int childWidthTemp[3], childHeightTemp[3];//用于存放图像分裂后的四块子图像的宽度和高度
int n, m, l;
n = (splitarea.top * Width + splitarea.left); // 该块图像的左上角像素值在数组中的下标
// 把图像分成4块,采用数组分别存储3个宽度值和3个高度值,该段程序可以处理该块图像的宽度或高度值为奇数的情况
childWidthTemp[0] = 0;
childWidthTemp[2] = (splitarea.w + 1) / 2;
childWidthTemp[1] = splitarea.w - childWidthTemp[2];//图像宽度为偶数的情况下, childWidthTemp[1]和childWidthTemp[2]无差别,
//奇数情况下childWidthTemp[2]-childWidthTemp[1]=1
childHeightTemp[0] = 0;
childHeightTemp[2] = (splitarea.h + 1) / 2;
childHeightTemp[1] = splitarea.h - childHeightTemp[2];//图像宽度为偶数的情况下, childHidthTemp[1]和childHidthTemp[2]无差别,
//奇数情况下childHidthTemp[2]-childHidthTemp[1]=1
// 计算每一块图像的属性值(均方差)
int Value;
int ValueTemp;
int i, j;//对分成的四块图像进行操作的循环
for(i = 1; i < 3; i++)
{
for(j = 1; j < 3; j++)
{
Value = 0;
m = (n + Width * childHeightTemp[i - 1] + childWidthTemp[j - 1]);
int x, y;
for(x = 0; x < childHeightTemp[i]; x++)
{
for(y = 0; y < childWidthTemp[j];y++)
{
l = (m + Width * x + y) ;//每块图像中各个像素点在存储数组中的位置下标
ValueTemp = srcImage[l];
Value = Value+ValueTemp;
}
}// 灰度值之和
if(childHeightTemp[i] * childWidthTemp[j] == 0)//分裂至最终结束时分裂块的宽度和高度其中有一个位0,那么分裂结束
{
continue;
}
if(childHeightTemp[i] * childWidthTemp[j] == 1)//分裂至单个像素时,将单个像素进行二值化
{
l = m;
if(srcImage[l] < 125)
{
srcImage[l]= 0;} else { srcImage[l] = 255; } continue; } // 各块图像的灰度平均值 int ValueS[2][2]; // 用于存储块图像的灰度值 ValueS[i - 1][j - 1] = Value / (childHeightTemp[i] * childWidthTemp[j]); int Value1=0,ValueTemp1; for(x = 0;x < childHeightTemp[i]; x++) { for(y = 0; y< childWidthTemp[j]; y++) { l = (m + Width * x + y) ; ValueTemp1 = srcImage[l]; Value1 = Value1+(ValueTemp1- ValueS[i - 1][j - 1])*(ValueTemp1- ValueS[i - 1][j - 1]); } } // 各块图像的均方差 int ValueS1[2][2]; // 用于存储块图像的均方差 ValueS1[i - 1][j - 1]= Value1 / (childHeightTemp[i] * childWidthTemp[j]); // 对每一块进行判断是否需要分裂 // 分裂原则: 图像的均方差超过某个阈值是需要分裂 if(ValueS1[i - 1][j - 1] > 100) // 均方差大于某个阈值时需要分裂 { SplitArea childarea; childarea.w = childWidthTemp[j]; childarea.h = childHeightTemp[i]; childarea.left = splitarea.left + childWidthTemp[j - 1]; childarea.top = splitarea.top + childHeightTemp[i - 1]; MyStack.push(childarea); } else // 如果不需要分裂, 则进行合并(直接填充该块图像为灰度值的平均值) { for(x = 0; x < childHeightTemp[i]; x++) { for(y = 0; y < childWidthTemp[j]; y++) { l = (m + Width * x + y) ; srcImage[l] =ValueS[i - 1][j - 1]; } } } } } } return;
}
int main (int argc, char * const argv[])
{
int rv;
int PixelFormat = 24, Width, Height;
unsigned char * pImg;
unsigned char * pBin;if ( argc < 2 ) { fprintf( stderr, "Usage: GetContour.exe imagen" ) ; return 0 ; } rv = viGetImageWH( argv[1], Width, Height ) ; if ( rv == 0 ) { printf( "Could not get image. Program exits!n" ); exit( 0 ); } pImg = new unsigned char [ Width*Height*PixelFormat/8 ]; viReadImageFile( argv[1], pImg, Width, Height, PixelFormat ); pBin = new unsigned char [Width*Height]; viColor24toGray8(pImg, Width, Height,1,pBin); areaSplitCombine( pBin, Width, Height); viNamedWindow( "Image", GUI_WINDOW_AUTOSIZE ); viShowImage( "Image",pBin, Width, Height, 8, 0 ); viWaitKey( 0 ); delete [] pImg; delete [] pBin; viDestroyAllWindows(); return 0;
}