PKU ACM 1009 Edge Detection 边缘提取算法

来源:互联网 发布:万科 股权 知乎 编辑:程序博客网 时间:2024/06/07 10:24

题目链接:Edge Detection 边缘提取算法

 

题目描述:

对输入图像进行边缘提取,算法是分别计算当前像素和周围8个像素之间的差,最大值就是提取后的像素值。

输入图像和输出图像都按照游程编码存储。

主要思路:

不能计算每个像素的值,会导致TL。其实,只在以下几种情况下,输出像素与前一个像素的值不同(变化点)

1. 输入图像中某个点对比前一个点发生了变化,那么它周围的 8 个点可能是输出图像中的变化点

2. 输入图像中某一行的像素值变化了,那么当前行的左右两个端点可能是输出图像中的变化点

 

源代码:

#include <iostream>using namespace std;struct Point{int pos;int val;Point* pNext;};struct RLE{int val;int len;};RLE iRLE[10000];Point* pFirst;int width;int iRLElen;int sum;int GetVal(int pos){int curpos = 0;if((pos >= 0) && (pos < iRLE[0].len))return iRLE[0].val;for(int i = 1; i < iRLElen; i++){curpos = curpos + iRLE[i-1].len;if((pos >= curpos) && (pos < curpos + iRLE[i].len))return iRLE[i].val;}return 0;}void GetBorderPoint(int pos){Point* pb = pFirst;Point* ppre = pFirst;while(pb != NULL){if(pb->pos == pos)return;if(pb->pos > pos)break;ppre = pb;pb = pb->pNext;}int surround[8] = {0};int max = 0;int val = GetVal(pos);if(pos >= width)surround[0] = abs(GetVal(pos - width) - val);if(pos < sum - width)surround[1] = abs(GetVal(pos + width) - val);if(pos % width > 0)surround[2] = abs(GetVal(pos - 1) - val);if(pos % width < width - 1)surround[3] = abs(GetVal(pos + 1) - val);if((pos >= width) && (pos % width > 0))surround[4] = abs(GetVal(pos - width - 1) - val);if((pos >= width) && (pos % width < width - 1))surround[5] = abs(GetVal(pos - width + 1) - val);if((pos < sum - width) && (pos % width > 0))surround[6] = abs(GetVal(pos + width - 1) - val);if((pos < sum - width) && (pos % width < width - 1))surround[7] = abs(GetVal(pos + width + 1) - val);for(int i = 0; i < 8; i++){if(surround[i] > max)max = surround[i];}if(pFirst == NULL){pFirst = new Point;pFirst->pos = pos;pFirst->val = max;pFirst->pNext = NULL;}else{Point* newpoint = new Point;newpoint->pos = pos;newpoint->val = max;newpoint->pNext  = pb;ppre->pNext = newpoint;}}void GetBorder(int pos){GetBorderPoint(pos);if(pos >= width)GetBorderPoint(pos - width);if(pos < sum - width)GetBorderPoint(pos + width);if(pos % width > 0)GetBorderPoint(pos - 1);if(pos % width < width - 1)GetBorderPoint(pos + 1);if((pos >= width) && (pos % width > 0))GetBorderPoint(pos - width - 1);if((pos >= width) && (pos % width < width - 1))GetBorderPoint(pos - width + 1);if((pos < sum - width) && (pos % width > 0))GetBorderPoint(pos + width - 1);if((pos < sum - width) && (pos % width < width - 1))GetBorderPoint(pos + width + 1);GetBorderPoint((pos / width) * width);GetBorderPoint((pos / width + 1) * width - 1);}void PrintResult(){cout << width << endl;Point* pb = pFirst;Point* preb = pFirst;int prepos = 0;int preval = pFirst->val;while(pb != NULL){if(pb->val != preval){cout << preval << " " << pb->pos - prepos << endl;preval = pb->val;prepos = pb->pos;}preb = pb;pb = pb->pNext;delete preb;}cout << preval << " " << sum - prepos << endl;cout << "0 0" << endl;}int main(){while(true){cin >> width;if(!width)break;iRLElen = 0;sum = 0;pFirst = NULL;memset(iRLE, 0, sizeof(iRLE));while(true){cin >> iRLE[iRLElen].val >> iRLE[iRLElen].len;sum = iRLE[iRLElen].len + sum;if(iRLE[iRLElen].len == 0)break;iRLElen++;}int curpos = 0;GetBorder(curpos);GetBorder(curpos + iRLE[0].len - 1);for(int i = 1; i < iRLElen; i++){curpos = curpos + iRLE[i-1].len;GetBorder(curpos);GetBorder(curpos + iRLE[i].len - 1);}PrintResult();}cout << "0" << endl;return 0;}

原创粉丝点击