1

我刚开始使用 Open CV 库,我的第一个代码之一是一个简单的负变换函数。

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void negative(Mat& input,Mat& output)
{
  int row = input.rows;
  int col = input.cols;
  int x,y;
  uchar *input_data=input.data;
  uchar *output_data= output.data;


  for( x=0;x<row;x++)
    for( y=0;y<col;y++)
      output_data[x*col+y]=255-input_data[x*col+y];

    cout<<x<<y;



}

int main( int argc, char** argv )
{
  Mat image;
  image = imread( argv[1], 1 );

  Mat output=image.clone();

  negative(image,output);

  namedWindow( "Display Image", CV_WINDOW_AUTOSIZE );
  imshow( "Display Image", output );

  waitKey(0);

  return 0;
}

我添加了额外的行来检查是否处理了整个图像。我的输出图像面临的问题是负变换仅应用于图像的上半部分。

现在发生的情况是 x 和 y 的值仅在我按下一个键后才显示(即一旦显示图像)

我的问题是为什么在执行函数之前调用窗口?

4

2 回答 2

2

代码中的基本问题是您正在阅读彩色图像,但您尝试将其处理为灰度图像。因此,索引会发生变化,真正发生的是您只处理图像的前三分之一(因为 3 通道格式)。

见 opencv imread 手册

flags – 指定加载图像的颜色类型:
>0 加载图像强制为 3 通道彩色图像
=0 加载图像强制为灰度

您已指定标志 = 1。

这是一种方法:

Vec3b v(255, 255, 255);
for(int i=0;i<input.rows;i++) //search for edges
{
    for (int j=0 ;j<input.cols;j++)
    {
        output.at<Vec3b>(i,j) = v - input.at<Vec3b>(i,j);
    }
}

请注意,这里的 Vec3b 是一个 3 通道像素值,而 uchar 是一个 1 通道值。
为了更有效的实现,您可以查看Mat.ptr<Vec3b>(i).

编辑:如果您正在处理大量图像,对于像素的一般迭代,最快的方法是:

Vec3b v(255, 255, 255); // or maybe Scalar v(255,255,255) Im not sure
for(int i=0;i<input.rows;i++) //search for edges
{
    Vec3b *p=input.ptr<Vec3b>(i);
    Vec3b *q=output.ptr<Vec3b>(i);
    for (int j=0 ;j<input.cols;j++)
    {
        q[j] = v - p[j];
    }
}

请参阅“OpenCV 教程”——“有效方式”部分。

于 2013-05-18T10:56:12.813 回答
1

试着写:

cout << x << y << endl;

该函数在之前被调用,但输出没有直接刷新,这导致您的图像在文本写入之前出现。通过添加“endline”,您可以强制刷新。您也可以使用flush(cout);而不是添加和结束行。


对于负数,您可以直接使用 OpenCV 函数减法()

subtract(Scalar(255, 255, 255), input, output);
于 2013-05-18T10:54:44.480 回答