问题描述
我正在尝试使用 OpenCV 学习图像处理。我写了一些代码来编辑图像。编辑工作正常,除了更改某些像素的颜色。
I am trying to learn image processing using OpenCV. I wrote some code to edit an image. The edits are working well except for changing the color of some pixels.
我试图访问一些随机像素,并改变它们的颜色(即<$ c $时) c> status == 3 )。当我运行程序时,我得到[run] Segmentation fault(core dumped)
,我认为这意味着存在被拒绝的内存访问。
I am trying to access some random pixels, and change their color (that is when status == 3
). When I run the program I get "[run] Segmentation fault (core dumped)"
, which I think means that there is a denied memory access.
int main( ) {
Mat originalImage = imread("image.jpg", CV_LOAD_IMAGE_UNCHANGED);
if (originalImage.empty()){
cout << "Error : Image cannot be loaded..!!" << endl;
return -1;
}
int orgRows = originalImage.rows;
int orgCols = originalImage.cols;
int status; // output indicator
cout << "Please select the settings" << endl;
cin >> status;
Mat displayedImage;
while (status != 0 ) {
if(status == 1){
// some code
}
else if (status == 2 ){
// some code
}else if (status == 3 ){
int j;
int k;
for (int i = 0; i < 1000; i++) {
j = rand()% orgCols;
k = rand() % orgRows;
Vec3b intensity = originalImage.at<Vec3b>(j, k);
intensity[0] = 255;
intensity[1] = 255;
intensity[2] = 255;
}
displayedImage = originalImage;
}else if (status == 4){
// some code
}else if (status == 5 ){
// some code
}else{
// some code
}
namedWindow("MyWindow",CV_WINDOW_AUTOSIZE);
imshow("MyWindow", displayedImage);
waitKey(1000);
destroyWindow("MyWindow");
cout << "Continue ? ... Please select the settings" << endl;
cin >> status;
}
return 0;
}
问题:
导致错误的原因是什么?如何解决?
Question:
What is causing the error and how could it be solved?
推荐答案
你有两个问题,都在这一行:
You have 2 problems, both on this line:
Vec3b intensity = originalImage.at<Vec3b>(j, k);
-
矩阵作为(row,col)访问,而不是(x,y)。所以你需要使用:
Vec3b intensity = originalImage.at< Vec3b>(j,k);
您正在复制像素bgr值。您在强度
上所做的每项更改都不会反映在 originalImage
中。您可以使用 originalImage
中的数据引用轻松纠正此问题: Vec3b&烈度= ...
。
You are copying the pixel bgr value. Every change you do on intensity
won't be reflected in originalImage
. You can easily correct this using a reference to the data in originalImage
: Vec3b& intensity = ...
.
因此,您需要更改上述内容line to:
As a result, you need to change the mentioned line to:
Vec3b& intensity = originalImage.at<Vec3b>(k, j);
注意:使用 intensity [0] = 255;
工作正常。您不需要使用 intensity.val [0] = 255;
Note: Using intensity[0] = 255;
works ok. You don't need to use intensity.val[0] = 255;
请注意,您可以做一些改进。
Note that there are some improvements that you can do.
1)因为您使用 Vec3b
type,你假设你的图像被读作 CV_8UC3
,即3通道矩阵,每通道8位深度。因此,如果您加载16位图像,或单通道(灰度)图像,或带有Alpha通道(RGBA)的图像,您的程序将崩溃。您可以在加载图片时强制执行 CV_8UC3
图片:
1) Since you work on Vec3b
type, you make the assumption that your image is read as CV_8UC3
, i.e. a 3 channel matrix, 8 bit depth per channel. So, if you load a 16bit image, or a single channel (grayscale) image, or an image with alpha channel (RGBA) your program will crash. You can enforce that you need a CV_8UC3
image while loading the image like:
Mat3b originalImage = imread("image.jpg", IMREAD_COLOR);
现在,你可以在<> ,因为图像类型是固定的。所以你可以这样做:
Now you can access the pixels value without the at<>
, since the image type is fixed. So you can do:
Vec3b& intensity = originalImage(k, j);
2)你可以简单地为 originalImage ,如:
2) You can simply assign a new value to
originalImage
, like:
originalImage.at<Vec3b>(k,j) = Vec3b(255,255,255);
//or
originalImage(k,j) = Vec3b(255,255,255); // If originalImage is a Mat3b
这篇关于使用for循环访问随机图像像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!