从这篇博客中看到3*3算子的操作 http://www.cnblogs.com/Imageshop/p/7285564.html
理解了一下,所以现在这里记录一下。
首先是,对于3*3算子,操作方式多为图像的3行一起操作。
其次,对于图像边缘,使用边缘像素延伸进行填充。
uint8_t srcimage[200*100];
int width = 100;
int height = 200;
int channel = 1;
/* +2是因为要多申请每一行的首尾的填充像素的内存 一共只申请三行内存*/
uint8_t *rowCopy = (uint8_t*)malloc((width+2)*3);
/* 第二行是因为要跳过第一行和首尾两个像素
第三行同理
*/
uint8_t *firstRow = rowCopy;
uint8_t *secondRow = rowCopy + width + 2;
uint8_t *thirdRow = rowCopy + (width + 2)*2;
/* 图像的第一行第一个像素 + 第一行所有像素 + 第一行最后一个像素
= 实现了 首尾边缘行像素的填充
*/
memcpy(firstRow,srcimage,channel);
memcpy(firstRow + channel,srcimage,width*channel);
memcpy(firstRow + (width + 1)*channel,srcimage + (width - 1)*channel,channel);
/* firstRow 存在的意义 也就是列方向的 像素填充 */
memcpy(secondRow,firstRow, (width + 2)*channel);
memcpy(thirdRow,srcimage + width*channel,channel);
memcpy(thirdRow + channel,srcimage + width*channel,width*channel);
memcpy(thirdRow + (width + 1)*channel,srcimage + width*channel + (width - 1)*channel,channel);
for(int y = 0;y<height;y++){
/* 如果不是第一行
因为第一行的话,数据局初始化已经复制过一行了
所以只需要进行把第二行变为第一行,
第三行变为第二行
这里指针变动,实际就是三片内存轮流使用,每个循环只操作一行的内存赋值
*/
if(y!=0){
uint8_t *temp = firstRow;
firstRow = secondRow;
secondRow = thirdRow;
thirdRow = temp;
}
/* 如果是最后一行
那么把第二行复制为第三行,也就是边缘列像素的填充
*/
if(y == height -1 ){
memcpy(thirdRow,secondRow,(width+2)*channel);
}
else{ /* 如果不是最后一行 那么第三行 就是下面*/
memcpy(thirdRow,srcimage + width*channel*(y+1),channel);
memcpy(thirdRow + channel,srcimage + width*channel*(y+1),width*channel);
memcpy(thirdRow + (width + 1)*channel,srcimage + width*channel*(y+1) + (width-1)*channel,channel);
}
if(channel == 1){
for(int x =0;x<width;x++){
/*
* 这里面就是数据的处理,
* x表示为图像行像素的索引
* 带入firstrow,secondrow,thirdrow,也能表示
* 对应的3*3算子位置
*/
qDebug()<<"["<<firstRow[x]<<firstRow[x+1]<<firstRow[x+2];
qDebug()<<secondRow[x]<<secondRow[x+1]<<secondRow[x+2];
qDebug()<<thirdRow[x]<<thirdRow[x+1]<<thirdRow[x+2]<<"]";
}
}
}