// 打開輸入和輸出文件 using FileStream fIn = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read); using FileStream fOut = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write);
byte[] imgHeader = new byte[54]; byte[] colorTable = new byte[1024];
// 讀取 BMP 標頭 int bytesRead = fIn.Read(imgHeader, 0, imgHeader.Length); if (bytesRead != imgHeader.Length) { Console.WriteLine("Unable to read image header"); return; }
// 打開輸入和輸出文件 using FileStream fIn = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read); using StreamWriter fOut = new StreamWriter(outputFilePath);
byte[] imgHeader = new byte[54];
int bytesRead = fIn.Read(imgHeader, 0, imgHeader.Length); if (bytesRead != imgHeader.Length) { Console.WriteLine("Unable to read image header"); return; }
int height = BitConverter.ToInt32(imgHeader, 22); int width = BitConverter.ToInt32(imgHeader, 18);
# 設定x軸範圍 set xlabel "Pixel Value" set xrange [0:255]
# 設定y軸範圍 set ylabel "Frequency"
# 設定顏色,這裡是紅色、綠色和藍色通道的顏色 set style line 1 linecolor rgb "blue" linetype 1 linewidth 2 set style line 2 linecolor rgb "green" linetype 1 linewidth 2 set style line 3 linecolor rgb "red" linetype 1 linewidth 2
# 繪製直方圖,使用三列資料,並設定不同顏色 plot "data3.txt" using 1 with lines linestyle 1 title "Blue", \ "data3.txt" using 2 with lines linestyle 2 title "Green", \ "data3.txt" using 3 with lines linestyle 3 title "Red"
或是用 python 來畫也可以, 這裡要注意 rgb 順序, js 是 rgb , c or c# 是 bgr
// 打開輸入和輸出文件 using FileStream fIn = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read); using FileStream fOut = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write); //using StreamWriter fOut = new StreamWriter(outputFilePath);
byte[] imgHeader = new byte[54]; byte[] colorTable = new byte[1024];
// 讀取 BMP 標頭 int bytesRead = fIn.Read(imgHeader, 0, imgHeader.Length); if (bytesRead != imgHeader.Length) { Console.WriteLine("Unable to read image header"); return; }
//因為已經讀過一次, 所以需要移動位置跳過 header 也可以用 Seek 函數 fIn.Position = 54; for (int i = 0; i < imgSize; i++) { var blue = fIn.ReadByte(); var green = fIn.ReadByte(); var red = fIn.ReadByte();
var blueEq = histEq[0, blue]; var greenEq = histEq[1, green]; var redEq = histEq[2, red];
void ImgHistogram(unsigned char * _imgData, int imgRows, int imgCols, float hist[]) { FILE *fptr; fptr = fopen("image_hist.txt","w"); int x,y,i,j; long int ihist[255]; long int sum;
for(i=0;i<=255;i++) { ihist[i] = 0; } sum =0; for(y =0;y<imgRows;y++) { for(x=0;x<imgCols;x++) { j = *(_imgData+x+y*imgCols); ihist[j] = ihist[j] +1; sum = sum +1;
} }
for( i =0;i<255;i++) { hist[i] = (float)ihist[i]/(float)sum;
// 打開輸入和輸出文件 using FileStream fIn = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read); using FileStream fOut = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write);
byte[] imgHeader = new byte[54]; byte[] colorTable = new byte[1024];
// 讀取 BMP 標頭 int bytesRead = fIn.Read(imgHeader, 0, imgHeader.Length); if (bytesRead != imgHeader.Length) { Console.WriteLine("Unable to read image header"); return; }
unsafe { //2D Discrete convolution void Convolve(int imgRows, int imgCols, Mask myMask, byte* input_buf, byte* output_buf) { long y, x, fy, fx, yIndex, xIndex; int ms, im = 0, val; byte* tmp;
//the outer summation loop for (y = 0; y < imgRows; ++y) for (x = 0; x < imgCols; ++x) { val = 0; for (fy = 0; fy < myMask.Rows; ++fy) for (fx = 0; fx < myMask.Cols; ++fx) { ms = *(myMask.Data + fy * myMask.Rows + fx); yIndex = y - fy; xIndex = x - fx; if (yIndex >= 0 && xIndex >= 0) im = *(input_buf + yIndex * imgRows + xIndex); val += ms * im; } if (val > 255) val = 255; if (val < 0) val = 0; tmp = output_buf + y * imgRows + x; *tmp = (byte)val; } } void Convolve2(int imgRows, int imgCols, Mask myMask, byte[] inputBuf, byte[] outputBuf) { int val; int ms, im = 0; int yIndex, xIndex;
// the outer summation loop for (int y = 0; y < imgRows; ++y) { for (int x = 0; x < imgCols; ++x) { val = 0;
// Iterate through the mask for (int fy = 0; fy < myMask.Rows; ++fy) { for (int fx = 0; fx < myMask.Cols; ++fx) { ms = *(myMask.Data + fy * myMask.Rows + fx);
yIndex = y - fy; xIndex = x - fx;
// Check if the indices are within bounds if (yIndex >= 0 && xIndex >= 0) { // Get the grayscale pixel value from the input buffer im = inputBuf[(yIndex * imgCols + xIndex)]; // For grayscale, it's just one value }
val += ms * im; // Apply the convolution operation } }
// Clamp the result to be between 0 and 255 if (val > 255) val = 255; if (val < 0) val = 0;
// Store the result back into the output buffer outputBuf[y * imgCols + x] = (byte)val; } } }
void ImageWriter(string imgName, byte[] header, byte[] colorTable, byte[] buf, int bitDepth) { using (FileStream fs = new FileStream(imgName, FileMode.Create, FileAccess.Write)) using (BinaryWriter writer = new BinaryWriter(fs)) { // Write the header writer.Write(header, 0, 54);
// Write the color table if bit depth is <= 8 if (bitDepth <= 8) { writer.Write(colorTable, 0, 1024); }
// Write the image buffer writer.Write(buf, 0, buf.Length); } }
void ImageReader(string imgName, out int height, out int width, out int bitDepth, byte[] header, byte[] colorTable, byte[] buf) { using (FileStream fs = new FileStream(imgName, FileMode.Open, FileAccess.Read)) using (BinaryReader reader = new BinaryReader(fs)) { // Read the header (54 bytes) reader.Read(header, 0, 54);
// Read the width, height, and bit depth width = BitConverter.ToInt32(header, 18); height = BitConverter.ToInt32(header, 22); bitDepth = BitConverter.ToInt16(header, 28);
// If the bit depth is <= 8, read the color table if (bitDepth <= 8) { reader.Read(colorTable, 0, 1024); }
// Read the image data reader.Read(buf, 0, buf.Length); } }
const int BMP_HEADER_SIZE = 54; const int BMP_COLOR_TABLE_SIZE = 1024; const int CUSTOM_IMG_SIZE = 256 * 256;
int imgWidth, imgHeight, imgBitDepth; byte[] imgHeader = new byte[BMP_HEADER_SIZE]; byte[] imgColorTable = new byte[BMP_COLOR_TABLE_SIZE]; byte[] imgBuffer = new byte[CUSTOM_IMG_SIZE]; byte[] imgBuffer2 = new byte[CUSTOM_IMG_SIZE];
using System.Runtime.InteropServices; int BMP_HEADER_SIZE = 54; int BMP_COLOR_TABLE_SIZE = 1024; int CUSTOM_IMG_SIZE = 512 * 512;
unsafe {
void ImageWriter(string imgName, byte* header, byte* colorTable, byte* buf, int bitDepth) { // 打開文件以寫入 using (FileStream fs = new FileStream(imgName, FileMode.Create, FileAccess.Write)) { using (BinaryWriter writer = new BinaryWriter(fs)) { // 寫入 header for (int i = 0; i < BMP_HEADER_SIZE; i++) { writer.Write(*(header + i)); }
// 如果位深度 <= 8,則寫入顏色表 if (bitDepth <= 8) { for (int i = 0; i < BMP_COLOR_TABLE_SIZE; i++) { writer.Write(*(colorTable + i)); } }
// 寫入圖像數據 for (int i = 0; i < CUSTOM_IMG_SIZE; i++) { writer.Write(*(buf + i)); } } } }
void ImageReader(string imgName, int* height, int* width, int* bitDepth, byte[] header, byte[] colorTable, byte[] buf) { using (FileStream fs = new FileStream(imgName, FileMode.Open, FileAccess.Read)) using (BinaryReader reader = new BinaryReader(fs)) { // Read the header (54 bytes) reader.Read(header, 0, 54);
// Read the width, height, and bit depth *width = BitConverter.ToInt32(header, 18); *height = BitConverter.ToInt32(header, 22); *bitDepth = BitConverter.ToInt16(header, 28);
// If the bit depth is <= 8, read the color table if (*bitDepth <= 8) { reader.Read(colorTable, 0, 1024); }
// Read the image data reader.Read(buf, 0, buf.Length); } }
void LineDetector(byte* _inputImgData, byte* _outputImgData, int imgCols, int imgRows, int[,] MASK) { int x, y, i, j, sum;
for (y = 1; y <= imgRows - 1; y++) { for (x = 1; x <= imgCols - 1; x++) { sum = 0; for (i = -1; i <= 1; i++) { for (j = -1; j <= 1; j++) { //這表示圖片目前的 pixel //*(_inputImgData + x + i + (long)(y + j) * imgCols)
//目前移動到 mask 的格子 //MASK[i + 1, j + 1] sum = sum + *(_inputImgData + x + i + (long)(y + j) * imgCols) * MASK[i + 1, j + 1]; } } if (sum > 255) sum = 255; if (sum < 0) sum = 0; *(_outputImgData + x + (long)y * imgCols) = (byte)sum; }
} }
void LineDetector2D(byte[,] _inputImgData, byte[,] _outputImgData, int imgCols, int imgRows, int[,] MASK) { int x, y, i, j, sum;
for (y = 1; y < imgRows - 1; y++) { for (x = 1; x < imgCols - 1; x++) { sum = 0; for (i = -1; i <= 1; i++) { for (j = -1; j <= 1; j++) { // 這是圖像目前的像素,改為直接使用二維陣列 sum = sum + _inputImgData[y + i, x + j] * MASK[i + 1, j + 1]; } }
// 確保像素值在 [0, 255] 範圍內 if (sum > 255) sum = 255; if (sum < 0) sum = 0;
void byteArrayTo2D(byte* buffer, byte[,] outBuffer) { for (int y = 0; y < 512; y++) { for (int x = 0; x < 512; x++) { outBuffer[y, x] = buffer[y * 512 + x]; } } }
int imgWidth; int imgHeight; int imgBitDepth; byte[] imgHeader = new byte[BMP_HEADER_SIZE]; byte[] imgColorTable = new byte[BMP_COLOR_TABLE_SIZE]; byte[] imgBuffer = new byte[CUSTOM_IMG_SIZE]; byte[] imgBuffer2 = new byte[CUSTOM_IMG_SIZE];
byte[,] imgBufferTwoD = new byte[512, 512]; byte[,] imgBuffer2TwoD = new byte[512, 512];
//read color table byte[] colorTable = new byte[1024]; if (bitDepth <= 8) { await bmpStream.ReadAsync(colorTable, 0, colorTable.Length); }
//圖片大小 int imgSize = height * width; using (var output = new MemoryStream()) { //write header await output.WriteAsync(imgHeader, 0, imgHeader.Length); if (bitDepth <= 8) { await output.WriteAsync(colorTable, 0, colorTable.Length); }
for (int i = 0; i < imgSize; i++) { var blue = (byte)bmpStream.ReadByte(); var green = (byte)bmpStream.ReadByte(); var red = (byte)bmpStream.ReadByte();
// 使用灰階公式:R * 0.299 + G * 0.587 + B * 0.114 int gray = (int)(red * 0.299 + green * 0.587 + blue * 0.114); output.WriteByte((byte)gray); output.WriteByte((byte)gray); output.WriteByte((byte)gray); }
int imgSize = height * width; unsigned char buffer[imgSize][3]; int mosaicSize = 5;
// 複製圖片 pixel 到最後要 out 的 buffer for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int current = x + y * width; buffer[current][0] = getc(fIn); buffer[current][1] = getc(fIn); buffer[current][2] = getc(fIn); } }
//loop pixel 步進值用 3 * 3 大小 for (int y = 0; y < height; y += mosaicSize) { for (int x = 0; x < width; x += mosaicSize) { //取得目前 pixel int current = x + y * width; int blue = buffer[current][0]; int green = buffer[current][1]; int red = buffer[current][2];
int imgSize = height * width; unsigned char buffer[imgSize][3]; int mosaicSize = 10;
// 複製圖片 pixel 到最後要 out 的 buffer for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int current = x + y * width; buffer[current][0] = getc(fIn); buffer[current][1] = getc(fIn); buffer[current][2] = getc(fIn); } }
// loop pixel 步進值用 3 * 3 大小 for (int y = 0; y < height; y += mosaicSize) { for (int x = 0; x < width; x += mosaicSize) { int sumBlue = 0; int sumGreen = 0; int sumRed = 0; int count = 0;
for (int my = 0; my < mosaicSize && (y + my) < height; my++) { for (int mx = 0; mx < mosaicSize && (x + mx) < width; mx++) { int current = (y + my) * width + (x + mx); sumBlue += buffer[current][0]; sumGreen += buffer[current][1]; sumRed += buffer[current][2]; count++; } }
int avgBlue = sumBlue / count; int avgGreen = sumGreen / count; int avgRed = sumRed / count;