我正在嘗試撰寫侵蝕過濾器。我嘗試確定我更改的部分,但我想將其他陣列元素填充為 255。我該怎么做?
public static byte[] dnmmmerosion(byte[] data)
{
int wdth = 2400;
int hght = 800;
List<byte> dnmbytee = new List<byte>();
byte[] dnmbyte = new byte[1200000];
for (int i = 0; i < 1200000; i )
{
dnmbytee[i] = 255;
}
for (int k = 1; k < hght-1; k )
{
for (int vvv = 0; vvv < wdth-1; vvv )
{
if (data[k vvv] == 0 && data[k *wdth vvv] == 0)
{
if (data[k * wdth (vvv 1)] == 0 && data[k * wdth vvv 2] == 0)
{
if (data[(k 1) * wdth vvv] == 0)
{
dnmbytee[k * wdth vvv 1] = 0;
}
}
}
}
}
for (int zzz = 0; zzz < 1200000; zzz )
{
dnmbyte[zzz] = dnmbytee[zzz];
}
return dnmbyte;
}
我的意思是我填充的元素在上面(比如:data[k vvv] == 0,...),我想我在創建回圈時犯了關于系數的錯誤
PS:當我寫這樣的代碼時,我只是看到了一個沉悶的觀點。

我正在對二進制影像進行處理。(所以陣列由 255 和 0 的元素組成。)如果結構的元素與影像中的元素相同(例如元素:1、2、3、4、5)寫 255到第 3 個元素。
uj5u.com熱心網友回復:
我不懂 C#,所以不會在代碼中解決一些我不理解的事情。
首先,你設定
int wdth = 2400;
int hght = 800;
但隨后為輸出緩沖區分配 1,200,000 位元組。這意味著您回圈了 2400 x 800 = 1,920,000 位元組,這遠遠超出了您的緩沖區。我想你的意思是設定hght = 500。為了避免這樣的問題,不要多次使用相同的數值,而是定義可以在代碼中使用的常量:
int channels = 3;
int width = 800; // let's not be lazy, and use real words as variable names!
int height = 500;
int buffer_size = channels * width * height;
byte[] dnmbyte = new byte[buffer_size];
for (int i = 0; i < buffer_size; i )
...
接下來,我不確定為什么需要中間緩沖區dnmbytee,為什么不能直接寫入dnmbyte. 不知道ListC# 中的 a 是什么,我假設它不是一個陣列,而是一個實際的串列資料結構。像你一樣使用這將非常昂貴,堅持使用陣列來存盤像素資料!
最后,主要問題是:您正在訪問緩沖區,就好像您有 2400 x 500 像素,每個像素一個位元組,而不是 800 x 500 像素,每個像素三個位元組 (RGB)。形態學操作在彩色影像上沒有很好的定義,所以我在這里假設一個像素的所有三個位元組總是相同的。如果是這樣,讀取每個像素的第一個位元組,并寫入所有三個位元組。
為此,您將像這樣回圈和索引:
for (int y = 1; y < height-1; y ) { // loop over all rows except the top and bottom-most ones
for (int x = 1; x < width-1; x ) { // loop over all columns, except the left and right-most ones
int current_pixel_index = (y * width x) * channels;
// read at data[current_pixel_index]
...
dnmbyte[current_pixel_index 0] = 0;
dnmbyte[current_pixel_index 1] = 0;
dnmbyte[current_pixel_index 2] = 0;
}
}
要訪問相鄰像素,您始終將相同的值添加到當前像素索引:channels將像素移至右側,-width*channels將像素移至頂部等。為結構元素中的每個像素創建一個串列,然后回圈串列:
int[5] neighbors;
neighbors[0] = -width*channels;
neighbors[1] = -channels;
neighbors[2] = 0;
neighbors[3] = channels;
neighbors[4] = width*channels;
for (int y = 1; y < height-1; y ) {
for (int x = 1; x < width-1; x ) {
int current_pixel_index = (y * width x) * channels;
for (int k = 0; k < 5; k ) {
// read at data[current_pixel_index neighbors[k]]
}
}
}
侵蝕邏輯可以是這樣的:
for (int k = 0; k < 5; k ) {
if (data[current_pixel_index neighbors[k]] == 0) {
dnmbyte[current_pixel_index 0] = 0;
dnmbyte[current_pixel_index 1] = 0;
dnmbyte[current_pixel_index 2] = 0;
break;
}
}
由于輸出陣列被初始化為 255,如果沒有一個鄰居是 0,它將保持在那個值。
The code above does not set any of the pixels at the edge of the image (first and last row and column). If you want to process those as well, the easiest method is to pad the input by one pixel at all sides, the new pixels should have a value of 255. The alternative is to do special processing at the edge pixels, where you ensure you don't attempt to read out of bounds. That type of processing tends to slow code down a lot, and also complicates the code. Padding is usually worth it!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/450085.html
上一篇:在OpenCV角點檢測中忽略數字
