显示使用纯C来自PGM图像(P5)直方图的像素值没有任何图像处理库 [英] Displaying histogram pixel values from PGM image (p5) using Pure C without any image processing library

查看:647
本文介绍了显示使用纯C来自PGM图像(P5)直方图的像素值没有任何图像处理库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这问题是具有挑战性的使用纯C.我做了一个简单的程序读取使用C非二进制文件的PGM使用GCC编译得到的图像处理更多的了解。现在,当我试图读取二进制文件PGM它正在成为一个问题。这种二进制文件PGM可转换的 JPG PGM 使用 IrvanView被收购

注意:请不要使用任何图像处理库(如:OpenCV的)答案。

我目前的code是:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
的#define WIDTH 1024
#定义高度768
#定义READ_IMAGE_NAMEMY_PGM_FILE_NAME.pgm无效print_histogram_table为(int *直方图);主(){
  FILE * FP;  INT I,J,身高=高度,宽度=宽度;
  焦线[100];  //颜色深度为255。
  unsigned char型pixel_value;  FP = FOPEN(READ_IMAGE_NAME,R);  //获得第一个四行。
  与fgets(行,100,FP);
  与fgets(行,100,FP);
  与fgets(行,100,FP);
  与fgets(行,100,FP);  //直方图帮手
  INT组织相容[65536]
  INT X;
  为(X = 0; X&下; 65536; X ++){
        HISTO [X] = 0;
  }  为(J = 0; J<高度; J ++){
     对于(i = 0; I<宽度;我++){
         FREAD(安培; pixel_value,sizeof的(无符号字符),1,FP);
         //打开code以下,如果要检查特定的行和列的颜色。
//输出(。排NUM%d栏NUM%d个像素值=%d个\\ N,J,I,pixel_value);       组织相容[pixel_value] ++;
     }
  }  //使直方图
  print_histogram_table(组织相容);  FCLOSE(FP);
  残培();
}无效print_histogram_table为(int *直方图)
{
  INT X;
  为(X = 0; X&所述; 255; X ++){
     如果(直方图[X]!= 0)
        的printf(颜色数量%d个计数%d个\\ N,X,直方图[X]);
  }
}

我已阅读有关我的问题有些页[如何阅读.PGM格式文件<? / A>],但我找不到任何明确和简单的答案。我在我的code任何错误道歉。任何关于我的code的建议和评论家将AP preciated。

我上面的脚本无法显示正确的颜色直方图,因为如果你想理性,你可能会得到100以上的像素颜色(不仅低于100)。所以,主要的问题是如何解决这个问题?

编辑我

编辑II


解决方案

  

我上面的脚本无法显示正确的颜色直方图,因为如果你想理性,你可能会得到100以上的像素颜色(不仅低于100)。所以,主要的问题是如何解决这个问题?


我假设你的意思是:


  

目前,该链接的图像上运行此程序只显示非零直方图条目像素值100以下。我在100以上的图像中知道至少有一个像素值的,所以有一个错误在我的code 。谁能帮我找出为什么出现这种情况?


我建议你重新词组你的问题,以明确这一点。

在code表面上看起来OK,假设你只希望它给你链接到图像上工作。但是,有很多可能加起来的小失误。下面是一些建议:

柱状图尺寸

首先,你不能打印整个直方图。考虑通过直方图大小,打印直方图的功能。此外,即使大小的没有的匹配(包括256),你仍然有一个错误。你永远不打印第256个值。

  INT组织相容[65536]
// ...
print_histogram_table(组织相容);
// ...
无效print_histogram_table为(int *直方图)
{
    INT X;
    为(X = 0; X&所述; 255; X ++){
       如果(直方图[X]!= 0)
          的printf(颜色数量%d个计数%d个\\ N,X,直方图[X]);
}

二进制I / O

您需要打开二进制文件时,指定二进制I / O。在UNIX上,传统上都没有区别,因为它是默认模式。但是,在Windows(我假设你运行的是Windows,因为你使用的伊尔凡视图),你需要明确指出你想二进制I / O。

这是首次二进制文件打交道时,一个常见的​​错误。基本上,只要 FREAD()呼叫捕获了一个 EOF 字节,它会的停止读取文件的,你会得到垃圾值,所有的后续读取(可能是最后真正的字节复印件),这意味着你没有真正读你的整个图像。

  FP = FOPEN(READ_IMAGE_NAME,R);
// 改成:
FP = FOPEN(READ_IMAGE_NAME,RB);

其他小的关注

有没有你的code处理的事情负载:


  1. PNM文件可以具有在文件的开头
  2. 注释
  3. 行可能有超过100个字符。

  4. 图片大小不强行1024×768

  5. 这是没多大用的硬code程序中的文件的名称,即使仅是测试你的code。

  6. 如果你真正得到一个16位每像素灰度图像,你的直方图是够大的,但你应该读2个字节的值。

This question is challenging to get more understanding on Image Processing using pure C. I have done a simple program reading non-binary PGM file using C compiled with GCC. Now, it is becoming a problem when I try to read binary PGM file. This binary PGM file can be acquired by converting JPG to PGM using IrvanView.

NOTE: Please don't answer with any image processing library (such as: OpenCV).

My current code is:

#include    <stdio.h> 
#include    <stdlib.h>
#define WIDTH 1024  
#define HEIGHT 768
#define READ_IMAGE_NAME "MY_PGM_FILE_NAME.pgm"

void print_histogram_table(int *histog);

main() {
  FILE *fp;

  int i,j, height= HEIGHT, width=WIDTH;
  char line[100];

  // Color depth is 255. 
  unsigned char pixel_value;

  fp = fopen(READ_IMAGE_NAME,"r");

  // get the first four lines.
  fgets (line,100,fp); 
  fgets (line,100,fp);
  fgets (line,100,fp);
  fgets (line,100,fp);

  // Histogram helper
  int histo[65536];
  int x;
  for ( x =0; x < 65536; x++) {    
        histo[x] = 0;
  }

  for(j=0;j<height;j++) {
     for(i=0;i<width;i++) {
         fread(&pixel_value, sizeof(unsigned char), 1, fp);
         // Turn on the code below, if you want to check color on specific row and column.
//             printf("row num. %d column num. %d    pixel value=%d\n",j,i,pixel_value);  

       histo[pixel_value]++;
     }
  }

  // Make histogram
  print_histogram_table(histo);

  fclose(fp);       
  getch();
}

void print_histogram_table(int *histog)
{
  int x; 
  for (x= 0; x < 255; x++) {
     if ( histog[x] != 0)
        printf("Color number %d count %d\n", x, histog[x]); 
  }
}

I have read some pages related to my problem [How to read .PGM format file?] , but I cannot find any clear and simple answer. I apologize for any mistake in my code. Any suggestion and critic regarding my code would be appreciated.

My script above could not display correct color histogram, because if you think rationally, you might get pixel color above 100 (not only below 100). So, the main question is How to fix this problem?

EDIT I

EDIT II

解决方案

My script above could not display correct color histogram, because if you think rationally, you might get pixel color above 100 (not only below 100). So, the main question is How to fix this problem?

I'm assuming you mean:

Right now, running this program on the linked image only displays non-zero histogram entries for pixel values below 100. I know of at least one pixel value in the image above 100, so there's a bug in my code. Can anyone help me figure out why this happens?

I suggest you re-phrase your question to make this clear.

The code superficially looks OK, assuming you only want it to work on the image you linked to. However, there a lots of small mistakes that may add up. Here are a few suggestions:

Histogram size

First, you can't print your entire histogram. Consider passing the histogram size to the function that prints the histogram. Moreover, even if the sizes did match (both 256), you would still have an error. You never print the 256th value.

int histo[65536];
// ...
print_histogram_table(histo);
// ...
void print_histogram_table(int *histog)
{
    int x; 
    for (x= 0; x < 255; x++) {
       if ( histog[x] != 0)
          printf("Color number %d count %d\n", x, histog[x]); 
}

Binary I/O

You need to specify "binary" I/O when opening binary files. On UNIX, this traditionally makes no difference because it is the default mode. However, on Windows (I'm assuming your running Windows since you're using Irfan View), you need to explicitly state that you want binary I/O.

This is a common mistake when dealing with binary files for the first time. Basically, as soon as the fread() call catches an EOF byte, it will stop reading the file and you will get garbage values for all subsequent reads (probably copies of the last real byte), which means you're not actually reading your entire image.

fp = fopen(READ_IMAGE_NAME,"r");
// change to:
fp = fopen(READ_IMAGE_NAME,"rb");

Other minor concerns

There are loads of things not handled by your code:

  1. PNM files may have comments at the beginning of the file
  2. Lines may have more than 100 characters.
  3. Image size is not forcibly 1024x768
  4. It's not much use to hardcode the name of the file in the program, even for just testing your code.
  5. If you actually get a 16-bit-per-pixel grayscale image, your histogram is large enough, but you should be reading 2-byte values.

这篇关于显示使用纯C来自PGM图像(P5)直方图的像素值没有任何图像处理库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆