找图像边缘,在数字图像处理中有所涉及,处理像素。
题目意思就是计算出一个像素点与周围像素点的差值中绝对值最大 作为输出,边界点无需计算边界处。
输入格式,第一个数字就是图像宽度,像素点的值以数值,对数的方式输入,这样就可以唯一确定一张图的长宽,序列0 0表示一副图的输入结束标志。
提示中指出:为每个像素点计算,可能会因为空间或者时间的限制,0而失败。
另附游程编码的拓展,多应用于黑白图像编码百科介绍
参考文章中除了用到库函数的快速排序,还用到了指向函数的指针
另外,数组中的.pos写法与[pos]等价
之所以最后对输出图进行排序是因为,编码虽然按序移动,但是对周遭八个点编码,所以,要按照pos重新排序
另,getcode中的tpos==pos-1条件是跳过中心像素点,因为,传入的当前处理的像素点的位置参数是从1开始的
由于边界处理不注意,一直不ac,研究别人代码也用了三天,还是要仔细coding
ac code:
#include <iostream>
#include<cstring>
#include <cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct pix{
public:
int pos;
int code;
};
int inmap[1000][2];
int width; //图像宽度
int pixpair; //对数
int total;//像素点总个数
//每个pix都依赖其周围的8个点编码
pix outmap[1000*8];
int cmp(pix a,pix b)
{
return a.pos<b.pos;
}
//获得在原图上的像素值
int getValue(int pos)
{
int p=0,i=0;
while(p<pos)
p=p+inmap[i++][1];
return inmap[i-1][0];
}
int getCode(int pos)
{
int code = getValue(pos);
int tempmax=0;
int row=(pos-1)/width;//排
int col=(pos-1)%width;//列
for(int i=row-1;i<=row+1;i++)
for(int j=col-1;j<=col+1;j++)
{
int tpos=i*width+j;
//tpos=pos-1的条件是跳过对中心点的编码
if(i<0 ||j>=width||j<0||tpos==pos-1||tpos>=total)
continue;
int temp =getValue(tpos+1);
if(tempmax<abs(temp-code))
tempmax=abs(temp-code);
}
return tempmax;
}
int main()
{
while(cin>>width&&width>0)
{
int value,length;
pixpair=0,total=0;
while(cin>>value>>length&&length>0)
{
inmap[pixpair][0] = value;
inmap[pixpair++][1] = length;
total+=length;
}
cout<<width<<endl;
int pos=1,k=0;//k为小的像素点
for(int p=0;p<=pixpair;p++)
{
int row=(pos-1)/width;//排
int col=(pos-1)%width;//列
for(int i = row-1;i<=row+1;i++)
{
for(int j = col-1;j<=col+1;j++)
{
int tpos = i*width+j;
if(i<0||j<0||j>=width||tpos>=total)
continue;
outmap[k].pos = tpos+1;
outmap[k++].code = getCode(tpos+1);
}
}
pos+=inmap[p][1];
}
sort(outmap,outmap+k,cmp);
pix temp =outmap[0];
for(int i=0;i<k;i++)
{
if(outmap[i].code==temp.code)
continue;
cout<<temp.code<<' '<<outmap[i].pos-temp.pos<<endl;
temp = outmap[i];
}
cout<<temp.code<<' '<<total-temp.pos+1<<endl;
cout<<"0 0"<<endl;
}
cout<<"0"<<endl;
return 0;
}