D. *_*anz 6 c++ opencv image-processing
我正在尝试通过自己做一些事来学习OpenCV.在这种特殊情况下,我想拍摄灰度图像的位平面.代码似乎有效,但它只适用于第7位和第6位,而不是其余6位,因为它只显示约1/3图像的良好结果.我还没有发现它有什么问题.我非常感谢有关此问题的一些帮助,因为我只是在编写我的第一个代码库.
这是我得到的第一位:
这是第7位:
这是我的代码:
#include <opencv2\opencv.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main( int argc, char** argv ) {
Mat m1 = imread("grayscalerose.jpg");
imshow("Original",m1);
int cols, rows, x, y;
cols = m1.cols;
rows = m1.rows;
printf("%d %d \n",m1.rows,m1.cols);
Mat out1(rows, cols, CV_8UC1, Scalar(0));
out1 = (m1/128); //Here's where I divide by either 1,2,4,8,16,32,64, or 128 to get the corresponding bit planes
for (int y = 0; y < rows; y++){
for (int x = 0; x < cols; x++){
out1.at<uchar>(y,x) = (out1.at<uchar>(y,x) % 2);
} }
out1 = out1*255;
imshow("out1",out1);
waitKey(0);
destroyWindow( "out1" );
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.我希望我的解释不是太乱.
首先让我们仅以灰度读取图像。(如user3896254 所述)。
然后,让我们准备一个掩码图像,其中只设置最低有效位——即所有值都是 1。
那么算法就简单了。让我们避免逐像素操作(两个嵌套的 for 循环),并尝试利用 OpenCV 提供的优化操作。
对于每一位(0..7):
代码:
#include <opencv2\opencv.hpp>
#include <cstdint>
int main(int argc, char** argv)
{
cv::Mat input_img(cv::imread("peppers.png", 0));
int32_t rows(input_img.rows), cols(input_img.cols);
cv::Mat bit_mask(cv::Mat::ones(rows, cols, CV_8UC1));
cv::Mat work_img(input_img.clone());
std::string file_name("peppers_bit0.png");
for (uint32_t i(0); i < 8; ++i) {
cv::Mat out;
cv::bitwise_and(work_img, bit_mask, out);
out *= 255;
cv::imwrite(file_name, out);
work_img = work_img / 2;
file_name[11] += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用单个矩阵表达式开发更短(可能更快)的版本。
我们可以使用表达式计算适当的除数(1<<i)
。我们将每个元素除以这个值以移动位,通过与 1 进行 AND 运算来屏蔽每个元素,然后将所有元素缩放 255:
#include <opencv2\opencv.hpp>
#include <cstdint>
int main(int argc, char** argv)
{
cv::Mat input_img(cv::imread("peppers.png", 0));
std::string file_name("peppers_bit0.png");
for (uint32_t i(0); i < 8; ++i) {
cv::Mat out(((input_img / (1<<i)) & 1) * 255);
cv::imwrite(file_name, out);
file_name[11] += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
输入图像:
位 0:
位 1:
位 2:
位 3:
位 4:
位 5:
位 6:
位 7:
当您将15
( 0x00001111
)除以2
( 0x00000010
) 时,您会得到7
( 0x00000111
),这不是您所期望的。您可以检查某个位是否已设置,如:15 & 2
,如果未设置第二位,则生成 0,否则生成大于 0 的值。这同样适用于其他值。
尝试以下代码。注意:
IMREAD_GRAYSCALE
in imread
)0
,也可以255
在选择位时输入值代码:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat m1 = imread("path_to_image", IMREAD_GRAYSCALE);
imshow("Original", m1);
int cols, rows, x, y;
cols = m1.cols;
rows = m1.rows;
printf("%d %d \n", m1.rows, m1.cols);
Mat out1(rows, cols, CV_8UC1, Scalar(0));
for (int y = 0; y < rows; y++){
for (int x = 0; x < cols; x++){
out1.at<uchar>(y, x) = (m1.at<uchar>(y, x) & uchar(64)) ? uchar(255) : uchar(0); //Here's where I AND by either 1,2,4,8,16,32,64, or 128 to get the corresponding bit planes
}
}
imshow("out1", out1);
waitKey(0);
destroyWindow("out1");
return 0;
}
Run Code Online (Sandbox Code Playgroud)