In python language, we can use A[A!=0]=-10
to trans all the non-zero value in A to -10. How can I implement this function in C language or is here any similar function in 3rd party?
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat A(3, 3, CV_16SC1);
for (int i = 0; i < 3; i )
{
for (int j = 0; j < 3; j )
{
A.at<short>(i, j) = i j;
}
}
for (auto& value : A) if (value != 2) value = -10;
}
CodePudding user response:
There is std::ranges::replace
in C 20:
std::vector<int> values = {1,2,3,1,2,5,3,165};
std::ranges::replace(values, 3, 999);
And, similarly, std::ranges::replace_if
in C 20:
std::vector<int> values = {1,2,0,1,0,5,3,165};
std::ranges::replace_if(values, [](int a) { return a != 0;}, -10);
You can see it in compiler explorer
Edit: here is the bind_front
code (from the above link):
std::ranges::replace_if(values, std::bind_front(std::not_equal_to{}, 0), -20);
CodePudding user response:
In STL container there is a function that has similar behavior. For example:
#include <vector>
#include <algorithm>
int main() {
using namespace std;
vector<int> example_vector{0,1,4,1,5};
for_each(example_vector.begin(), example_vector.end(), [](auto& a) { if (a != 0)a = -10; });
}
Although the syntax seems not simple like python, it is optimized, and may be parallelized by execution policy.
CodePudding user response:
Range-based for
loops will not work since the cv::Mat::begin()
is a member function template. You'll have to use begin<mat_type>()
and end<mat_type>()
.
Example:
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
int main() {
cv::Mat A(3, 3, CV_16SC1);
using mtype = short; // convenience typedef
for(int i = 0; i < 3; i ) {
for(int j = 0; j < 3; j ) {
A.at<mtype>(i, j) = i j; // using mtype
}
}
// using mtype:
for(auto it = A.begin<mtype>(); it != A.end<mtype>(); it) {
if(*it != 2) *it = -10;
}
// print result:
std::copy(A.begin<mtype>(), A.end<mtype>(),
std::ostream_iterator<mtype>(std::cout, "\n"));
}
Or using the std::replace_if
algorithm to replace all non 2
's with -10
:
std::replace_if(A.begin<mtype>(), A.end<mtype>(), // using mtype
[](auto& value) { return value != 2; }, -10);
Output:
-10
-10
2
-10
2
-10
2
-10
-10